[deploy] Add KGE_RENDER_ENGINE macro

This commit is contained in:
Nomango 2020-02-14 22:59:29 +08:00
parent 94915b87ff
commit f1e0d59cea
23 changed files with 362 additions and 222 deletions

View File

@ -233,7 +233,7 @@ inline bool Time::IsZero() const
} }
} // namespace kiwano } // namespace kiwano
#if defined(KGE_VS_VER) && KGE_VS_VER > KGE_VS_2013 #if defined(KGE_HAS_LITERALS)
namespace kiwano namespace kiwano
{ {

View File

@ -51,26 +51,89 @@
// Compile-time Config Header File // Compile-time Config Header File
#include <kiwano/config.h> #include <kiwano/config.h>
#define KGE_NOT_USED(VAR) ((void)VAR)
#define KGE_RENDER_ENGINE_NONE 0
#define KGE_RENDER_ENGINE_OPENGL 1
#define KGE_RENDER_ENGINE_OPENGLES 2
#define KGE_RENDER_ENGINE_DIRECTX 3
#define KGE_RENDER_ENGINE KGE_RENDER_ENGINE_NONE
/////////////////////////////////////////////////////////////
//
// Windows platform // Windows platform
//
/////////////////////////////////////////////////////////////
#ifdef KGE_WIN32 #ifdef KGE_WIN32
#ifndef _MSC_VER #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_NONE
# error Kiwano only supports MSVC compiler # undef KGE_RENDER_ENGINE
# define KGE_RENDER_ENGINE KGE_RENDER_ENGINE_DIRECTX
#endif #endif
#ifndef KGE_VS_VER #ifdef _MSC_VER
# define KGE_VS_VER _MSC_VER # ifndef KGE_VS_VER
# define KGE_VS_2013 1800 # define KGE_VS_VER _MSC_VER
# define KGE_VS_2015 1900 # define KGE_VS_2013 1800
# define KGE_VS_2017 1900 # define KGE_VS_2015 1900
# define KGE_VS_2019 1920 # define KGE_VS_2017 1900
# define KGE_VS_2019 1920
# endif
# if KGE_VS_VER < KGE_VS_2015
# error Kiwano only supports Visual Studio 2015 and above
# endif
# if defined(KGE_VS_VER) && KGE_VS_VER > KGE_VS_2013
# define KGE_HAS_LITERALS
# endif
#endif #endif
#if KGE_VS_VER < KGE_VS_2015 #if defined(DEBUG) || defined(_DEBUG)
# error Kiwano only supports Visual Studio 2015 and above # define KGE_DEBUG
#endif #endif
#ifndef KGE_ASSERT
# ifdef KGE_DEBUG
# define KGE_ASSERT(EXPR) \
do \
{ \
(void)((!!(EXPR)) || (_wassert(_CRT_WIDE(#EXPR), _CRT_WIDE(__FUNCTION__), (unsigned)(__LINE__)), 0)); \
} while (0)
# else
# define KGE_ASSERT __noop
# endif
#endif
#define KGE_DEPRECATED(...) __declspec(deprecated(__VA_ARGS__))
#define KGE_SUPPRESS_WARNING_PUSH __pragma(warning(push))
#define KGE_SUPPRESS_WARNING(CODE) __pragma(warning(disable : CODE))
#define KGE_SUPPRESS_WARNING_POP __pragma(warning(pop))
#ifndef KGE_API
# if defined(KGE_USE_DLL)
# define KGE_API __declspec(dllimport)
# elif defined(KGE_EXPORT_DLL)
# define KGE_API __declspec(dllexport)
# endif
#endif
#ifndef KGE_API
/* Building or calling Kiwano as a static library */
# define KGE_API
#else
/*
* C4251 can be ignored if you are deriving from a type in the
* C++ Standard Library, compiling a debug release (/MTd) and
* where the compiler error message refers to _Container_base.
*/
KGE_SUPPRESS_WARNING(4251)
#endif
#ifndef WINVER #ifndef WINVER
# define WINVER 0x0700 // Allow use of features specific to Windows 7 or later # define WINVER 0x0700 // Allow use of features specific to Windows 7 or later
#endif #endif
@ -96,52 +159,8 @@
# define NOMINMAX # define NOMINMAX
#endif #endif
#if defined(DEBUG) || defined(_DEBUG)
# define KGE_DEBUG
#endif
#define KGE_SUPPRESS_WARNING_PUSH __pragma(warning(push))
#define KGE_SUPPRESS_WARNING(CODE) __pragma(warning(disable : CODE))
#define KGE_SUPPRESS_WARNING_POP __pragma(warning(pop))
#ifndef KGE_ASSERT
# ifdef KGE_DEBUG
# define KGE_ASSERT(EXPR) \
do \
{ \
(void)((!!(EXPR)) || (_wassert(_CRT_WIDE(#EXPR), _CRT_WIDE(__FUNCTION__), (unsigned)(__LINE__)), 0)); \
} while (0)
# else
# define KGE_ASSERT __noop
# endif
#endif
#ifndef KGE_API
# if defined(KGE_USE_DLL)
# define KGE_API __declspec(dllimport)
# elif defined(KGE_EXPORT_DLL)
# define KGE_API __declspec(dllexport)
# endif
#endif
#ifndef KGE_API
/* Building or calling Kiwano as a static library */
# define KGE_API
#else
/*
* C4251 can be ignored if you are deriving from a type in the
* C++ Standard Library, compiling a debug release (/MTd) and
* where the compiler error message refers to _Container_base.
*/
KGE_SUPPRESS_WARNING(4251)
#endif
#define KGE_DEPRECATED(...) __declspec(deprecated(__VA_ARGS__))
// Windows Header Files // Windows Header Files
#include <wincodec.h> #include <wincodec.h>
#include <windows.h> #include <windows.h>
#endif // KGE_WIN32 #endif // KGE_WIN32
#define KGE_NOT_USED(VAR) ((void)VAR)

View File

@ -40,7 +40,7 @@ Application::Application()
Application::~Application() {} Application::~Application() {}
void Application::Run(Runner* runner, bool debug) void Application::Run(RunnerPtr runner, bool debug)
{ {
KGE_ASSERT(runner); KGE_ASSERT(runner);
runner_ = runner; runner_ = runner;

View File

@ -52,15 +52,6 @@ public:
*/ */
void Run(RunnerPtr runner, bool debug = false); void Run(RunnerPtr runner, bool debug = false);
/**
* \~chinese
* @brief
* @param runner
* @param debug
* @note
*/
void Run(Runner* runner, bool debug = false);
/** /**
* \~chinese * \~chinese
* @brief * @brief
@ -126,7 +117,7 @@ public:
/** /**
* \~chinese * \~chinese
* @brief * @brief
*/ */
void Render(); void Render();
@ -139,11 +130,6 @@ private:
Queue<Function<void()>> functions_to_perform_; Queue<Function<void()>> functions_to_perform_;
}; };
inline void Application::Run(RunnerPtr runner, bool debug)
{
this->Run(runner.get(), debug);
}
inline RunnerPtr Application::GetRunner() const inline RunnerPtr Application::GetRunner() const
{ {
return runner_; return runner_;

View File

@ -90,11 +90,6 @@ Brush::Brush()
{ {
} }
bool Brush::IsValid() const
{
return raw_ != nullptr;
}
void Brush::SetColor(Color const& color) void Brush::SetColor(Color const& color)
{ {
Renderer::GetInstance().CreateBrush(*this, color); Renderer::GetInstance().CreateBrush(*this, color);

View File

@ -139,7 +139,7 @@ public:
private: private:
Type type_; Type type_;
#if defined(KGE_WIN32) #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
public: public:
void SetBrush(ComPtr<ID2D1Brush> brush, Type type); void SetBrush(ComPtr<ID2D1Brush> brush, Type type);
@ -157,7 +157,16 @@ inline Brush::Type Brush::GetType() const
return type_; return type_;
} }
#if defined(KGE_WIN32) inline bool Brush::IsValid() const
{
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
return raw_ != nullptr;
#else
return false; // not supported
#endif
}
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
inline void Brush::SetBrush(ComPtr<ID2D1Brush> brush, Type type) inline void Brush::SetBrush(ComPtr<ID2D1Brush> brush, Type type)
{ {
type_ = type; type_ = type;

View File

@ -587,33 +587,6 @@ void RendererImpl::CreateFontCollection(Font& font, Resource const& res)
ThrowIfFailed(hr, "Create font collection failed"); ThrowIfFailed(hr, "Create font collection failed");
} }
void RendererImpl::CreateTextFormat(TextLayout& layout)
{
HRESULT hr = S_OK;
if (!d2d_res_)
{
hr = E_UNEXPECTED;
}
ComPtr<IDWriteTextFormat> output;
if (SUCCEEDED(hr))
{
const TextStyle& style = layout.GetStyle();
hr = d2d_res_->CreateTextFormat(
output, MultiByteToWide(style.font_family).c_str(), 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))
{
layout.SetTextFormat(output);
}
ThrowIfFailed(hr, "Create text format failed");
}
void RendererImpl::CreateTextLayout(TextLayout& layout) void RendererImpl::CreateTextLayout(TextLayout& layout)
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
@ -622,17 +595,54 @@ void RendererImpl::CreateTextLayout(TextLayout& layout)
hr = E_UNEXPECTED; hr = E_UNEXPECTED;
} }
ComPtr<IDWriteTextLayout> output; if (layout.GetText().empty())
if (SUCCEEDED(hr))
{ {
WideString text = MultiByteToWide(layout.GetText()); layout.SetTextFormat(nullptr);
layout.SetTextLayout(nullptr);
hr = d2d_res_->CreateTextLayout(output, text.c_str(), text.length(), layout.GetTextFormat()); return;
} }
if (SUCCEEDED(hr)) if (!layout.GetTextFormat() || (layout.GetDirtyFlag() & TextLayout::DirtyFlag::DirtyFormat))
{ {
layout.SetTextLayout(output); ComPtr<IDWriteTextFormat> output;
if (SUCCEEDED(hr))
{
const TextStyle& style = layout.GetStyle();
hr = d2d_res_->CreateTextFormat(output, MultiByteToWide(style.font_family).c_str(),
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))
{
layout.SetTextFormat(output);
}
}
if (layout.GetDirtyFlag() & TextLayout::DirtyFlag::DirtyLayout)
{
ComPtr<IDWriteTextLayout> output;
if (SUCCEEDED(hr))
{
WideString text = MultiByteToWide(layout.GetText());
hr = d2d_res_->CreateTextLayout(output, text.c_str(), text.length(), layout.GetTextFormat());
}
if (SUCCEEDED(hr))
{
layout.SetTextLayout(output);
layout.SetAlignment(layout.GetStyle().alignment);
layout.SetWrapWidth(layout.GetStyle().wrap_width);
layout.SetLineSpacing(layout.GetStyle().line_spacing);
layout.SetDirtyFlag(TextLayout::DirtyFlag::Clean);
}
} }
ThrowIfFailed(hr, "Create text layout failed"); ThrowIfFailed(hr, "Create text layout failed");

View File

@ -58,8 +58,6 @@ public:
void CreateFontCollection(Font& font, Resource const& res) override; void CreateFontCollection(Font& font, Resource const& res) override;
void CreateTextFormat(TextLayout& layout) override;
void CreateTextLayout(TextLayout& layout) override; void CreateTextLayout(TextLayout& layout) override;
void CreateLineShape(Shape& shape, Point const& begin_pos, Point const& end_pos) override; void CreateLineShape(Shape& shape, Point const& begin_pos, Point const& end_pos) override;

View File

@ -62,7 +62,11 @@ public:
/// @brief 加载字体资源 /// @brief 加载字体资源
bool Load(Resource const& resource); bool Load(Resource const& resource);
#if defined(KGE_WIN32) /// \~chinese
/// @brief 是否有效
bool IsValid() const;
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
public: public:
ComPtr<IDWriteFontCollection> GetCollection() const; ComPtr<IDWriteFontCollection> GetCollection() const;
@ -75,7 +79,16 @@ private:
/** @} */ /** @} */
#if defined(KGE_WIN32) inline bool Font::IsValid() const
{
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
return collection_ != nullptr;
#else
return false; // not supported
#endif
}
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
inline ComPtr<IDWriteFontCollection> Font::GetCollection() const inline ComPtr<IDWriteFontCollection> Font::GetCollection() const
{ {
return collection_; return collection_;

View File

@ -82,11 +82,6 @@ bool GifImage::Load(Resource const& res)
return false; return false;
} }
bool GifImage::IsValid() const
{
return decoder_ != nullptr;
}
GifImage::Frame GifImage::GetFrame(uint32_t index) GifImage::Frame GifImage::GetFrame(uint32_t index)
{ {
Frame frame; Frame frame;
@ -94,7 +89,7 @@ GifImage::Frame GifImage::GetFrame(uint32_t index)
return frame; return frame;
} }
#if defined(KGE_WIN32) #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
bool GifImage::GetGlobalMetadata() bool GifImage::GetGlobalMetadata()
{ {
HRESULT hr = decoder_ ? S_OK : E_FAIL; HRESULT hr = decoder_ ? S_OK : E_FAIL;
@ -193,6 +188,14 @@ bool GifImage::GetGlobalMetadata()
} }
return SUCCEEDED(hr); return SUCCEEDED(hr);
} }
#else
bool GifImage::GetGlobalMetadata()
{
return false; // not supported
}
#endif #endif
} // namespace kiwano } // namespace kiwano

View File

@ -108,7 +108,7 @@ private:
uint32_t width_in_pixels_; uint32_t width_in_pixels_;
uint32_t height_in_pixels_; uint32_t height_in_pixels_;
#if defined(KGE_WIN32) #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
public: public:
ComPtr<IWICBitmapDecoder> GetDecoder() const; ComPtr<IWICBitmapDecoder> GetDecoder() const;
@ -141,7 +141,16 @@ inline uint32_t GifImage::GetFramesCount() const
return frames_count_; return frames_count_;
} }
#if defined(KGE_WIN32) inline bool GifImage::IsValid() const
{
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
return decoder_ != nullptr;
#else
return false; // not supported
#endif
}
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
inline ComPtr<IWICBitmapDecoder> GifImage::GetDecoder() const inline ComPtr<IWICBitmapDecoder> GifImage::GetDecoder() const
{ {
return decoder_; return decoder_;

View File

@ -80,7 +80,7 @@ private:
ShapePtr mask_; ShapePtr mask_;
Matrix3x2 mask_transform_; Matrix3x2 mask_transform_;
#if defined(KGE_WIN32) #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
public: public:
ComPtr<ID2D1Layer> GetLayer() const; ComPtr<ID2D1Layer> GetLayer() const;
@ -95,7 +95,11 @@ private:
inline bool Layer::IsValid() const inline bool Layer::IsValid() const
{ {
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
return layer_ != nullptr; return layer_ != nullptr;
#else
return false; // not supported
#endif
} }
inline Rect const& Layer::GetClipRect() const inline Rect const& Layer::GetClipRect() const
@ -138,7 +142,7 @@ inline void Layer::SetMaskTransform(Matrix3x2 const& matrix)
mask_transform_ = matrix; mask_transform_ = matrix;
} }
#if defined(KGE_WIN32) #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
inline ComPtr<ID2D1Layer> Layer::GetLayer() const inline ComPtr<ID2D1Layer> Layer::GetLayer() const
{ {
return layer_; return layer_;

View File

@ -113,12 +113,6 @@ public:
/// @throw std::system_error 创建失败时抛出 /// @throw std::system_error 创建失败时抛出
virtual void CreateFontCollection(Font& font, Resource const& res) = 0; virtual void CreateFontCollection(Font& font, Resource const& res) = 0;
/// \~chinese
/// @brief 创建文字格式内部资源
/// @param[out] layout 字体布局
/// @throw std::system_error 创建失败时抛出
virtual void CreateTextFormat(TextLayout& layout) = 0;
/// \~chinese /// \~chinese
/// @brief 创建文字布局内部资源 /// @brief 创建文字布局内部资源
/// @param[out] layout 字体布局 /// @param[out] layout 字体布局

View File

@ -27,13 +27,9 @@ namespace kiwano
Shape::Shape() {} Shape::Shape() {}
bool Shape::IsValid() const
{
return geo_ != nullptr;
}
Rect Shape::GetBoundingBox() const Rect Shape::GetBoundingBox() const
{ {
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
Rect bounds; Rect bounds;
if (geo_) if (geo_)
{ {
@ -41,10 +37,14 @@ Rect Shape::GetBoundingBox() const
geo_->GetBounds(nullptr, DX::ConvertToRectF(&bounds)); geo_->GetBounds(nullptr, DX::ConvertToRectF(&bounds));
} }
return bounds; return bounds;
#else
return Rect(); // not supported
#endif
} }
Rect Shape::GetBoundingBox(Matrix3x2 const& transform) const Rect Shape::GetBoundingBox(Matrix3x2 const& transform) const
{ {
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
Rect bounds; Rect bounds;
if (geo_) if (geo_)
{ {
@ -52,10 +52,14 @@ Rect Shape::GetBoundingBox(Matrix3x2 const& transform) const
geo_->GetBounds(DX::ConvertToMatrix3x2F(transform), DX::ConvertToRectF(&bounds)); geo_->GetBounds(DX::ConvertToMatrix3x2F(transform), DX::ConvertToRectF(&bounds));
} }
return bounds; return bounds;
#else
return Rect(); // not supported
#endif
} }
float Shape::GetLength() const float Shape::GetLength() const
{ {
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
float length = 0.f; float length = 0.f;
if (geo_) if (geo_)
{ {
@ -63,10 +67,14 @@ float Shape::GetLength() const
geo_->ComputeLength(D2D1::Matrix3x2F::Identity(), &length); geo_->ComputeLength(D2D1::Matrix3x2F::Identity(), &length);
} }
return length; return length;
#else
return 0.0f; // not supported
#endif
} }
bool Shape::ComputePointAtLength(float length, Point& point, Vec2& tangent) const bool Shape::ComputePointAtLength(float length, Point& point, Vec2& tangent) const
{ {
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
if (geo_) if (geo_)
{ {
HRESULT hr = geo_->ComputePointAtLength(length, D2D1::Matrix3x2F::Identity(), DX::ConvertToPoint2F(&point), HRESULT hr = geo_->ComputePointAtLength(length, D2D1::Matrix3x2F::Identity(), DX::ConvertToPoint2F(&point),
@ -75,15 +83,23 @@ bool Shape::ComputePointAtLength(float length, Point& point, Vec2& tangent) cons
return SUCCEEDED(hr); return SUCCEEDED(hr);
} }
return false; return false;
#else
return false; // not supported
#endif
} }
void Shape::Clear() void Shape::Clear()
{ {
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
geo_.reset(); geo_.reset();
#else
return; // not supported
#endif
} }
float Shape::ComputeArea() const float Shape::ComputeArea() const
{ {
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
if (!geo_) if (!geo_)
return 0.f; return 0.f;
@ -91,10 +107,14 @@ float Shape::ComputeArea() const
// no matter it failed or not // no matter it failed or not
geo_->ComputeArea(D2D1::Matrix3x2F::Identity(), &area); geo_->ComputeArea(D2D1::Matrix3x2F::Identity(), &area);
return area; return area;
#else
return 0.0f; // not supported
#endif
} }
bool Shape::ContainsPoint(Point const& point, const Matrix3x2* transform) const bool Shape::ContainsPoint(Point const& point, const Matrix3x2* transform) const
{ {
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
if (!geo_) if (!geo_)
return false; return false;
@ -103,6 +123,9 @@ bool Shape::ContainsPoint(Point const& point, const Matrix3x2* transform) const
geo_->FillContainsPoint(DX::ConvertToPoint2F(point), DX::ConvertToMatrix3x2F(transform), geo_->FillContainsPoint(DX::ConvertToPoint2F(point), DX::ConvertToMatrix3x2F(transform),
D2D1_DEFAULT_FLATTENING_TOLERANCE, &ret); D2D1_DEFAULT_FLATTENING_TOLERANCE, &ret);
return !!ret; return !!ret;
#else
return false; // not supported
#endif
} }
ShapePtr Shape::CreateLine(Point const& begin, Point const& end) ShapePtr Shape::CreateLine(Point const& begin, Point const& end)

View File

@ -111,7 +111,7 @@ public:
/// @brief 清除形状 /// @brief 清除形状
void Clear(); void Clear();
#if defined(KGE_WIN32) #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
public: public:
ComPtr<ID2D1Geometry> GetGeometry() const; ComPtr<ID2D1Geometry> GetGeometry() const;
@ -124,7 +124,16 @@ private:
/** @} */ /** @} */
#if defined(KGE_WIN32) inline bool Shape::IsValid() const
{
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
return geo_ != nullptr;
#else
return false; // not supported
#endif
}
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
inline ComPtr<ID2D1Geometry> Shape::GetGeometry() const inline ComPtr<ID2D1Geometry> Shape::GetGeometry() const
{ {
return geo_; return geo_;

View File

@ -33,6 +33,7 @@ ShapeSink::~ShapeSink()
void ShapeSink::Open() void ShapeSink::Open()
{ {
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
if (!IsOpened()) if (!IsOpened())
{ {
path_geo_.reset(); path_geo_.reset();
@ -40,10 +41,14 @@ void ShapeSink::Open()
ThrowIfFailed(path_geo_->Open(&sink_), "Open ID2D1GeometrySink failed"); ThrowIfFailed(path_geo_->Open(&sink_), "Open ID2D1GeometrySink failed");
} }
#else
return; // not supported
#endif
} }
void ShapeSink::Close() void ShapeSink::Close()
{ {
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
if (IsOpened()) if (IsOpened())
{ {
ThrowIfFailed(sink_->Close(), "Close ID2D1GeometrySink failed"); ThrowIfFailed(sink_->Close(), "Close ID2D1GeometrySink failed");
@ -52,11 +57,18 @@ void ShapeSink::Close()
shape_ = new Shape; shape_ = new Shape;
shape_->SetGeometry(path_geo_); shape_->SetGeometry(path_geo_);
#else
return; // not supported
#endif
} }
bool ShapeSink::IsOpened() const bool ShapeSink::IsOpened() const
{ {
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
return sink_ != nullptr; return sink_ != nullptr;
#else
return false; // not supported
#endif
} }
ShapePtr ShapeSink::GetShape() ShapePtr ShapeSink::GetShape()
@ -72,6 +84,7 @@ ShapeSink& ShapeSink::AddShape(ShapePtr input, const Matrix3x2* input_matrix)
Open(); Open();
} }
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
if (input && input->IsValid()) if (input && input->IsValid())
{ {
ComPtr<ID2D1Geometry> geo = input->GetGeometry(); ComPtr<ID2D1Geometry> geo = input->GetGeometry();
@ -81,6 +94,9 @@ ShapeSink& ShapeSink::AddShape(ShapePtr input, const Matrix3x2* input_matrix)
ThrowIfFailed(hr, "Get outline of ID2D1Geometry failed"); ThrowIfFailed(hr, "Get outline of ID2D1Geometry failed");
} }
return (*this); return (*this);
#else
return (*this); // not supported
#endif
} }
ShapeSink& ShapeSink::BeginPath(Point const& begin_pos) ShapeSink& ShapeSink::BeginPath(Point const& begin_pos)
@ -90,52 +106,80 @@ ShapeSink& ShapeSink::BeginPath(Point const& begin_pos)
Open(); Open();
} }
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
sink_->BeginFigure(DX::ConvertToPoint2F(begin_pos), D2D1_FIGURE_BEGIN_FILLED); sink_->BeginFigure(DX::ConvertToPoint2F(begin_pos), D2D1_FIGURE_BEGIN_FILLED);
#else
// not supported
#endif
return (*this); return (*this);
} }
ShapeSink& ShapeSink::EndPath(bool closed) ShapeSink& ShapeSink::EndPath(bool closed)
{ {
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
KGE_ASSERT(sink_); KGE_ASSERT(sink_);
sink_->EndFigure(closed ? D2D1_FIGURE_END_CLOSED : D2D1_FIGURE_END_OPEN); sink_->EndFigure(closed ? D2D1_FIGURE_END_CLOSED : D2D1_FIGURE_END_OPEN);
#else
// not supported
#endif
return (*this); return (*this);
} }
ShapeSink& ShapeSink::AddLine(Point const& point) ShapeSink& ShapeSink::AddLine(Point const& point)
{ {
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
KGE_ASSERT(sink_); KGE_ASSERT(sink_);
sink_->AddLine(DX::ConvertToPoint2F(point)); sink_->AddLine(DX::ConvertToPoint2F(point));
#else
// not supported
#endif
return (*this); return (*this);
} }
ShapeSink& ShapeSink::AddLines(Vector<Point> const& points) ShapeSink& ShapeSink::AddLines(Vector<Point> const& points)
{ {
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
KGE_ASSERT(sink_); KGE_ASSERT(sink_);
sink_->AddLines(reinterpret_cast<const D2D_POINT_2F*>(&points[0]), static_cast<uint32_t>(points.size())); sink_->AddLines(reinterpret_cast<const D2D_POINT_2F*>(&points[0]), static_cast<uint32_t>(points.size()));
#else
// not supported
#endif
return (*this); return (*this);
} }
ShapeSink& kiwano::ShapeSink::AddLines(const Point* points, size_t count) ShapeSink& kiwano::ShapeSink::AddLines(const Point* points, size_t count)
{ {
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
KGE_ASSERT(sink_); KGE_ASSERT(sink_);
sink_->AddLines(reinterpret_cast<const D2D_POINT_2F*>(points), UINT32(count)); sink_->AddLines(reinterpret_cast<const D2D_POINT_2F*>(points), UINT32(count));
#else
// not supported
#endif
return (*this); return (*this);
} }
ShapeSink& ShapeSink::AddBezier(Point const& point1, Point const& point2, Point const& point3) ShapeSink& ShapeSink::AddBezier(Point const& point1, Point const& point2, Point const& point3)
{ {
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
KGE_ASSERT(sink_); KGE_ASSERT(sink_);
sink_->AddBezier( sink_->AddBezier(
D2D1::BezierSegment(DX::ConvertToPoint2F(point1), DX::ConvertToPoint2F(point2), DX::ConvertToPoint2F(point3))); D2D1::BezierSegment(DX::ConvertToPoint2F(point1), DX::ConvertToPoint2F(point2), DX::ConvertToPoint2F(point3)));
#else
// not supported
#endif
return (*this); return (*this);
} }
ShapeSink& ShapeSink::AddArc(Point const& point, Size const& radius, float rotation, bool clockwise, bool is_small) ShapeSink& ShapeSink::AddArc(Point const& point, Size const& radius, float rotation, bool clockwise, bool is_small)
{ {
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
KGE_ASSERT(sink_); KGE_ASSERT(sink_);
sink_->AddArc(D2D1::ArcSegment(DX::ConvertToPoint2F(point), DX::ConvertToSizeF(radius), rotation, sink_->AddArc(D2D1::ArcSegment(DX::ConvertToPoint2F(point), DX::ConvertToSizeF(radius), rotation,
clockwise ? D2D1_SWEEP_DIRECTION_CLOCKWISE : D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE, clockwise ? D2D1_SWEEP_DIRECTION_CLOCKWISE : D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE,
is_small ? D2D1_ARC_SIZE_SMALL : D2D1_ARC_SIZE_LARGE)); is_small ? D2D1_ARC_SIZE_SMALL : D2D1_ARC_SIZE_LARGE));
#else
// not supported
#endif
return (*this); return (*this);
} }
@ -146,6 +190,7 @@ ShapeSink& ShapeSink::Combine(ShapePtr shape_a, ShapePtr shape_b, CombineMode mo
Open(); Open();
} }
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
if (shape_a && shape_b) if (shape_a && shape_b)
{ {
ComPtr<ID2D1Geometry> geo_a_raw = shape_a->geo_; ComPtr<ID2D1Geometry> geo_a_raw = shape_a->geo_;
@ -155,6 +200,9 @@ ShapeSink& ShapeSink::Combine(ShapePtr shape_a, ShapePtr shape_b, CombineMode mo
DX::ConvertToMatrix3x2F(matrix), sink_.get()); DX::ConvertToMatrix3x2F(matrix), sink_.get());
ThrowIfFailed(hr, "Combine ID2D1Geometry failed"); ThrowIfFailed(hr, "Combine ID2D1Geometry failed");
} }
#else
// not supported
#endif
return (*this); return (*this);
} }
@ -162,7 +210,11 @@ void ShapeSink::Clear()
{ {
Close(); Close();
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
path_geo_.reset(); path_geo_.reset();
#else
// not supported
#endif
} }
} // namespace kiwano } // namespace kiwano

View File

@ -130,9 +130,9 @@ public:
void Clear(); void Clear();
private: private:
ShapePtr shape_; ShapePtr shape_;
#if defined(KGE_WIN32) #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
public: public:
ComPtr<ID2D1PathGeometry> GetPathGeometry() const; ComPtr<ID2D1PathGeometry> GetPathGeometry() const;
@ -150,7 +150,7 @@ private:
/** @} */ /** @} */
#if defined(KGE_WIN32) #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
inline ComPtr<ID2D1PathGeometry> ShapeSink::GetPathGeometry() const inline ComPtr<ID2D1PathGeometry> ShapeSink::GetPathGeometry() const
{ {
return path_geo_; return path_geo_;

View File

@ -112,6 +112,7 @@ void StrokeStyle::SetDashStyle(const float* dash_array, size_t dash_size)
style_.reset(); style_.reset();
} }
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
ComPtr<ID2D1StrokeStyle> StrokeStyle::GetStrokeStyle() const ComPtr<ID2D1StrokeStyle> StrokeStyle::GetStrokeStyle() const
{ {
StrokeStyle& self = const_cast<StrokeStyle&>(*this); StrokeStyle& self = const_cast<StrokeStyle&>(*this);
@ -122,5 +123,6 @@ ComPtr<ID2D1StrokeStyle> StrokeStyle::GetStrokeStyle() const
dash_offset_); dash_offset_);
return style_; return style_;
} }
#endif
} // namespace kiwano } // namespace kiwano

View File

@ -170,7 +170,7 @@ private:
float dash_offset_; float dash_offset_;
Vector<float> dash_array_; Vector<float> dash_array_;
#if defined(KGE_WIN32) #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
public: public:
ComPtr<ID2D1StrokeStyle> GetStrokeStyle() const; ComPtr<ID2D1StrokeStyle> GetStrokeStyle() const;
@ -221,12 +221,16 @@ inline void StrokeStyle::SetDashOffset(float dash_offset)
style_.reset(); style_.reset();
} }
#if defined(KGE_WIN32)
inline bool StrokeStyle::IsValid() const inline bool StrokeStyle::IsValid() const
{ {
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
return style_ != nullptr; return style_ != nullptr;
#else
return false; // not supported
#endif
} }
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
inline void StrokeStyle::SetStrokeStyle(ComPtr<ID2D1StrokeStyle> style) inline void StrokeStyle::SetStrokeStyle(ComPtr<ID2D1StrokeStyle> style)
{ {
style_ = style; style_ = style;

View File

@ -33,31 +33,7 @@ void TextLayout::Update()
if (!IsDirty()) if (!IsDirty())
return; return;
if (text_.empty()) Renderer::GetInstance().CreateTextLayout(*this);
{
text_format_.reset();
text_layout_.reset();
return;
}
if (!text_format_ || (dirty_flag_ & DirtyFlag::DirtyFormat))
{
Renderer::GetInstance().CreateTextFormat(*this);
}
if (dirty_flag_ & DirtyFlag::DirtyLayout)
{
Renderer::GetInstance().CreateTextLayout(*this);
if (text_layout_)
{
SetAlignment(style_.alignment);
SetWrapWidth(style_.wrap_width);
SetLineSpacing(style_.line_spacing);
}
}
dirty_flag_ = DirtyFlag::Updated;
} }
void TextLayout::SetText(const String& text) void TextLayout::SetText(const String& text)
@ -122,6 +98,7 @@ uint32_t TextLayout::GetLineCount() const
// Force to update layout // Force to update layout
const_cast<TextLayout*>(this)->Update(); const_cast<TextLayout*>(this)->Update();
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
if (text_layout_) if (text_layout_)
{ {
DWRITE_TEXT_METRICS metrics; DWRITE_TEXT_METRICS metrics;
@ -130,6 +107,9 @@ uint32_t TextLayout::GetLineCount() const
return metrics.lineCount; return metrics.lineCount;
} }
} }
#else
// not supported
#endif
return 0; return 0;
} }
@ -138,6 +118,7 @@ Size TextLayout::GetLayoutSize() const
// Force to update layout // Force to update layout
const_cast<TextLayout*>(this)->Update(); const_cast<TextLayout*>(this)->Update();
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
if (text_layout_) if (text_layout_)
{ {
DWRITE_TEXT_METRICS metrics; DWRITE_TEXT_METRICS metrics;
@ -147,6 +128,9 @@ Size TextLayout::GetLayoutSize() const
: Size(metrics.width, metrics.height); : Size(metrics.width, metrics.height);
} }
} }
#else
// not supported
#endif
return Size(); return Size();
} }
@ -154,6 +138,7 @@ void TextLayout::SetWrapWidth(float wrap_width)
{ {
style_.wrap_width = wrap_width; style_.wrap_width = wrap_width;
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
if (text_layout_) if (text_layout_)
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
@ -185,12 +170,16 @@ void TextLayout::SetWrapWidth(float wrap_width)
} }
ThrowIfFailed(hr, "Apply word wrapping to text layout failed"); ThrowIfFailed(hr, "Apply word wrapping to text layout failed");
} }
#else
return; // not supported
#endif
} }
void TextLayout::SetLineSpacing(float line_spacing) void TextLayout::SetLineSpacing(float line_spacing)
{ {
style_.line_spacing = line_spacing; style_.line_spacing = line_spacing;
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
if (text_layout_) if (text_layout_)
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
@ -204,17 +193,24 @@ void TextLayout::SetLineSpacing(float line_spacing)
} }
ThrowIfFailed(hr, "Apply line spacing to text layout failed"); ThrowIfFailed(hr, "Apply line spacing to text layout failed");
} }
#else
return; // not supported
#endif
} }
void TextLayout::SetAlignment(TextAlign align) void TextLayout::SetAlignment(TextAlign align)
{ {
style_.alignment = align; style_.alignment = align;
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
if (text_layout_) if (text_layout_)
{ {
HRESULT hr = text_layout_->SetTextAlignment(DWRITE_TEXT_ALIGNMENT(align)); HRESULT hr = text_layout_->SetTextAlignment(DWRITE_TEXT_ALIGNMENT(align));
ThrowIfFailed(hr, "Apply alignment style to text layout failed"); ThrowIfFailed(hr, "Apply alignment style to text layout failed");
} }
#else
return; // not supported
#endif
} }
void TextLayout::SetUnderline(bool enable, uint32_t start, uint32_t length) void TextLayout::SetUnderline(bool enable, uint32_t start, uint32_t length)
@ -222,6 +218,7 @@ void TextLayout::SetUnderline(bool enable, uint32_t start, uint32_t length)
// Force to update layout // Force to update layout
Update(); Update();
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
HRESULT hr = text_layout_ ? S_OK : E_FAIL; HRESULT hr = text_layout_ ? S_OK : E_FAIL;
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
@ -229,6 +226,9 @@ void TextLayout::SetUnderline(bool enable, uint32_t start, uint32_t length)
hr = text_layout_->SetUnderline(enable, { start, length }); hr = text_layout_->SetUnderline(enable, { start, length });
} }
ThrowIfFailed(hr, "Apply underline style to text layout failed"); ThrowIfFailed(hr, "Apply underline style to text layout failed");
#else
return; // not supported
#endif
} }
void TextLayout::SetStrikethrough(bool enable, uint32_t start, uint32_t length) void TextLayout::SetStrikethrough(bool enable, uint32_t start, uint32_t length)
@ -236,6 +236,7 @@ void TextLayout::SetStrikethrough(bool enable, uint32_t start, uint32_t length)
// Force to update layout // Force to update layout
Update(); Update();
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
HRESULT hr = text_layout_ ? S_OK : E_FAIL; HRESULT hr = text_layout_ ? S_OK : E_FAIL;
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
@ -243,6 +244,9 @@ void TextLayout::SetStrikethrough(bool enable, uint32_t start, uint32_t length)
hr = text_layout_->SetStrikethrough(enable, { start, length }); hr = text_layout_->SetStrikethrough(enable, { start, length });
} }
ThrowIfFailed(hr, "Apply strikethrough style to text layout failed"); ThrowIfFailed(hr, "Apply strikethrough style to text layout failed");
#else
return; // not supported
#endif
} }
} // namespace kiwano } // namespace kiwano

View File

@ -165,7 +165,7 @@ private:
String text_; String text_;
TextStyle style_; TextStyle style_;
#if defined(KGE_WIN32) #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
public: public:
ComPtr<IDWriteTextFormat> GetTextFormat() const; ComPtr<IDWriteTextFormat> GetTextFormat() const;
@ -185,7 +185,11 @@ private:
inline bool TextLayout::IsValid() const inline bool TextLayout::IsValid() const
{ {
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
return text_layout_ != nullptr; return text_layout_ != nullptr;
#else
return false; // not supported
#endif
} }
inline bool TextLayout::IsDirty() const inline bool TextLayout::IsDirty() const
@ -243,7 +247,7 @@ inline void TextLayout::SetOutlineStroke(StrokeStylePtr outline_stroke)
style_.outline_stroke = outline_stroke; style_.outline_stroke = outline_stroke;
} }
#if defined(KGE_WIN32) #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
inline ComPtr<IDWriteTextFormat> TextLayout::GetTextFormat() const inline ComPtr<IDWriteTextFormat> TextLayout::GetTextFormat() const
{ {
return text_format_; return text_format_;

View File

@ -67,65 +67,34 @@ bool Texture::Load(Resource const& res)
return IsValid(); return IsValid();
} }
bool Texture::IsValid() const
{
return bitmap_ != nullptr;
}
float Texture::GetWidth() const float Texture::GetWidth() const
{ {
if (bitmap_) return size_.x;
{
return bitmap_->GetSize().width;
}
return 0;
} }
float Texture::GetHeight() const float Texture::GetHeight() const
{ {
if (bitmap_) return size_.y;
{
return bitmap_->GetSize().height;
}
return 0;
} }
Size Texture::GetSize() const Size Texture::GetSize() const
{ {
if (bitmap_) return size_;
{
auto bitmap_size = bitmap_->GetSize();
return Size{ bitmap_size.width, bitmap_size.height };
}
return Size{};
} }
uint32_t Texture::GetWidthInPixels() const uint32_t Texture::GetWidthInPixels() const
{ {
if (bitmap_) return size_in_pixels_.x;
{
return bitmap_->GetPixelSize().width;
}
return 0;
} }
uint32_t Texture::GetHeightInPixels() const uint32_t Texture::GetHeightInPixels() const
{ {
if (bitmap_) return size_in_pixels_.y;
{
return bitmap_->GetPixelSize().height;
}
return 0;
} }
math::Vec2T<uint32_t> Texture::GetSizeInPixels() const math::Vec2T<uint32_t> Texture::GetSizeInPixels() const
{ {
if (bitmap_) return size_in_pixels_;
{
auto bitmap_size = bitmap_->GetPixelSize();
return math::Vec2T<uint32_t>{ bitmap_size.width, bitmap_size.height };
}
return math::Vec2T<uint32_t>{};
} }
InterpolationMode Texture::GetBitmapInterpolationMode() const InterpolationMode Texture::GetBitmapInterpolationMode() const
@ -135,16 +104,21 @@ InterpolationMode Texture::GetBitmapInterpolationMode() const
void Texture::CopyFrom(TexturePtr copy_from) void Texture::CopyFrom(TexturePtr copy_from)
{ {
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
if (IsValid() && copy_from) if (IsValid() && copy_from)
{ {
HRESULT hr = bitmap_->CopyFromBitmap(nullptr, copy_from->GetBitmap().get(), nullptr); HRESULT hr = bitmap_->CopyFromBitmap(nullptr, copy_from->GetBitmap().get(), nullptr);
ThrowIfFailed(hr, "Copy texture data failed"); ThrowIfFailed(hr, "Copy texture data failed");
} }
#else
return; // not supported
#endif
} }
void Texture::CopyFrom(TexturePtr copy_from, Rect const& src_rect, Point const& dest_point) void Texture::CopyFrom(TexturePtr copy_from, Rect const& src_rect, Point const& dest_point)
{ {
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
if (IsValid() && copy_from) if (IsValid() && copy_from)
{ {
HRESULT hr = bitmap_->CopyFromBitmap( HRESULT hr = bitmap_->CopyFromBitmap(
@ -154,6 +128,9 @@ void Texture::CopyFrom(TexturePtr copy_from, Rect const& src_rect, Point const&
ThrowIfFailed(hr, "Copy texture data failed"); ThrowIfFailed(hr, "Copy texture data failed");
} }
#else
return; // not supported
#endif
} }
void Texture::SetInterpolationMode(InterpolationMode mode) void Texture::SetInterpolationMode(InterpolationMode mode)
@ -180,16 +157,4 @@ InterpolationMode Texture::GetDefaultInterpolationMode()
return default_interpolation_mode_; return default_interpolation_mode_;
} }
#if defined(KGE_WIN32)
ComPtr<ID2D1Bitmap> Texture::GetBitmap() const
{
return bitmap_;
}
void Texture::SetBitmap(ComPtr<ID2D1Bitmap> bitmap)
{
bitmap_ = bitmap;
}
#endif
} // namespace kiwano } // namespace kiwano

View File

@ -132,7 +132,7 @@ private:
static InterpolationMode default_interpolation_mode_; static InterpolationMode default_interpolation_mode_;
#if defined(KGE_WIN32) #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
public: public:
/// \~chinese /// \~chinese
/// @brief 获取源位图 /// @brief 获取源位图
@ -143,10 +143,47 @@ public:
void SetBitmap(ComPtr<ID2D1Bitmap> bitmap); void SetBitmap(ComPtr<ID2D1Bitmap> bitmap);
private: private:
ComPtr<ID2D1Bitmap> bitmap_; ComPtr<ID2D1Bitmap> bitmap_;
Size size_;
math::Vec2T<uint32_t> size_in_pixels_;
#endif #endif
}; };
/** @} */ /** @} */
inline bool Texture::IsValid() const
{
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
return bitmap_ != nullptr;
#else
return false; // not supported
#endif
}
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
inline ComPtr<ID2D1Bitmap> Texture::GetBitmap() const
{
return bitmap_;
}
inline void Texture::SetBitmap(ComPtr<ID2D1Bitmap> bitmap)
{
if (bitmap_ != bitmap)
{
bitmap_ = bitmap;
if (bitmap_)
{
auto size = bitmap_->GetSize();
auto pixel_size = bitmap_->GetPixelSize();
size_.x = size.width;
size_.y = size.height;
size_in_pixels_.x = pixel_size.width;
size_in_pixels_.y = pixel_size.height;
}
}
}
#endif
} // namespace kiwano } // namespace kiwano