From f1e0d59cea27cc96e0300b76fb11d7b5ec11e36a Mon Sep 17 00:00:00 2001 From: Nomango Date: Fri, 14 Feb 2020 22:59:29 +0800 Subject: [PATCH] [deploy] Add KGE_RENDER_ENGINE macro --- src/kiwano/core/Time.h | 2 +- src/kiwano/macros.h | 127 ++++++++++++--------- src/kiwano/platform/Application.cpp | 2 +- src/kiwano/platform/Application.h | 16 +-- src/kiwano/render/Brush.cpp | 5 - src/kiwano/render/Brush.h | 13 ++- src/kiwano/render/DirectX/RendererImpl.cpp | 78 +++++++------ src/kiwano/render/DirectX/RendererImpl.h | 2 - src/kiwano/render/Font.h | 17 ++- src/kiwano/render/GifImage.cpp | 15 ++- src/kiwano/render/GifImage.h | 13 ++- src/kiwano/render/Layer.h | 8 +- src/kiwano/render/Renderer.h | 6 - src/kiwano/render/Shape.cpp | 33 +++++- src/kiwano/render/Shape.h | 13 ++- src/kiwano/render/ShapeSink.cpp | 52 +++++++++ src/kiwano/render/ShapeSink.h | 6 +- src/kiwano/render/StrokeStyle.cpp | 2 + src/kiwano/render/StrokeStyle.h | 8 +- src/kiwano/render/TextLayout.cpp | 54 +++++---- src/kiwano/render/TextLayout.h | 8 +- src/kiwano/render/Texture.cpp | 63 +++------- src/kiwano/render/Texture.h | 41 ++++++- 23 files changed, 362 insertions(+), 222 deletions(-) diff --git a/src/kiwano/core/Time.h b/src/kiwano/core/Time.h index 85458384..e18d415b 100644 --- a/src/kiwano/core/Time.h +++ b/src/kiwano/core/Time.h @@ -233,7 +233,7 @@ inline bool Time::IsZero() const } } // namespace kiwano -#if defined(KGE_VS_VER) && KGE_VS_VER > KGE_VS_2013 +#if defined(KGE_HAS_LITERALS) namespace kiwano { diff --git a/src/kiwano/macros.h b/src/kiwano/macros.h index b90537ef..b4378327 100644 --- a/src/kiwano/macros.h +++ b/src/kiwano/macros.h @@ -51,26 +51,89 @@ // Compile-time Config Header File #include +#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 +// +///////////////////////////////////////////////////////////// #ifdef KGE_WIN32 -#ifndef _MSC_VER -# error Kiwano only supports MSVC compiler +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_NONE +# undef KGE_RENDER_ENGINE +# define KGE_RENDER_ENGINE KGE_RENDER_ENGINE_DIRECTX #endif -#ifndef KGE_VS_VER -# define KGE_VS_VER _MSC_VER -# define KGE_VS_2013 1800 -# define KGE_VS_2015 1900 -# define KGE_VS_2017 1900 -# define KGE_VS_2019 1920 +#ifdef _MSC_VER +# ifndef KGE_VS_VER +# define KGE_VS_VER _MSC_VER +# define KGE_VS_2013 1800 +# define KGE_VS_2015 1900 +# 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 -#if KGE_VS_VER < KGE_VS_2015 -# error Kiwano only supports Visual Studio 2015 and above +#if defined(DEBUG) || defined(_DEBUG) +# define KGE_DEBUG #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 # define WINVER 0x0700 // Allow use of features specific to Windows 7 or later #endif @@ -96,52 +159,8 @@ # define NOMINMAX #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 #include #include #endif // KGE_WIN32 - -#define KGE_NOT_USED(VAR) ((void)VAR) diff --git a/src/kiwano/platform/Application.cpp b/src/kiwano/platform/Application.cpp index efd45494..470d83f2 100644 --- a/src/kiwano/platform/Application.cpp +++ b/src/kiwano/platform/Application.cpp @@ -40,7 +40,7 @@ Application::Application() Application::~Application() {} -void Application::Run(Runner* runner, bool debug) +void Application::Run(RunnerPtr runner, bool debug) { KGE_ASSERT(runner); runner_ = runner; diff --git a/src/kiwano/platform/Application.h b/src/kiwano/platform/Application.h index 49e6cad5..05de1225 100644 --- a/src/kiwano/platform/Application.h +++ b/src/kiwano/platform/Application.h @@ -52,15 +52,6 @@ public: */ void Run(RunnerPtr runner, bool debug = false); - /** - * \~chinese - * @brief 启动应用程序 - * @param runner 程序运行器 - * @param debug 是否启用调试模式 - * @note 该函数是阻塞的,应用程序结束时函数返回 - */ - void Run(Runner* runner, bool debug = false); - /** * \~chinese * @brief 终止应用程序 @@ -126,7 +117,7 @@ public: /** * \~chinese - * @brief 渲染 + * @brief 创建渲染上下文并渲染画面 */ void Render(); @@ -139,11 +130,6 @@ private: Queue> functions_to_perform_; }; -inline void Application::Run(RunnerPtr runner, bool debug) -{ - this->Run(runner.get(), debug); -} - inline RunnerPtr Application::GetRunner() const { return runner_; diff --git a/src/kiwano/render/Brush.cpp b/src/kiwano/render/Brush.cpp index f5e6250f..6c744814 100644 --- a/src/kiwano/render/Brush.cpp +++ b/src/kiwano/render/Brush.cpp @@ -90,11 +90,6 @@ Brush::Brush() { } -bool Brush::IsValid() const -{ - return raw_ != nullptr; -} - void Brush::SetColor(Color const& color) { Renderer::GetInstance().CreateBrush(*this, color); diff --git a/src/kiwano/render/Brush.h b/src/kiwano/render/Brush.h index 3826065a..1ad2d0e4 100644 --- a/src/kiwano/render/Brush.h +++ b/src/kiwano/render/Brush.h @@ -139,7 +139,7 @@ public: private: Type type_; -#if defined(KGE_WIN32) +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX public: void SetBrush(ComPtr brush, Type type); @@ -157,7 +157,16 @@ inline Brush::Type Brush::GetType() const 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 brush, Type type) { type_ = type; diff --git a/src/kiwano/render/DirectX/RendererImpl.cpp b/src/kiwano/render/DirectX/RendererImpl.cpp index 6a7e5a78..0782cc51 100644 --- a/src/kiwano/render/DirectX/RendererImpl.cpp +++ b/src/kiwano/render/DirectX/RendererImpl.cpp @@ -587,33 +587,6 @@ void RendererImpl::CreateFontCollection(Font& font, Resource const& res) ThrowIfFailed(hr, "Create font collection failed"); } -void RendererImpl::CreateTextFormat(TextLayout& layout) -{ - HRESULT hr = S_OK; - if (!d2d_res_) - { - hr = E_UNEXPECTED; - } - - ComPtr 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) { HRESULT hr = S_OK; @@ -622,17 +595,54 @@ void RendererImpl::CreateTextLayout(TextLayout& layout) hr = E_UNEXPECTED; } - ComPtr output; - if (SUCCEEDED(hr)) + if (layout.GetText().empty()) { - WideString text = MultiByteToWide(layout.GetText()); - - hr = d2d_res_->CreateTextLayout(output, text.c_str(), text.length(), layout.GetTextFormat()); + layout.SetTextFormat(nullptr); + layout.SetTextLayout(nullptr); + return; } - if (SUCCEEDED(hr)) + if (!layout.GetTextFormat() || (layout.GetDirtyFlag() & TextLayout::DirtyFlag::DirtyFormat)) { - layout.SetTextLayout(output); + ComPtr 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 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"); diff --git a/src/kiwano/render/DirectX/RendererImpl.h b/src/kiwano/render/DirectX/RendererImpl.h index a9e1712d..eae5d49b 100644 --- a/src/kiwano/render/DirectX/RendererImpl.h +++ b/src/kiwano/render/DirectX/RendererImpl.h @@ -58,8 +58,6 @@ public: void CreateFontCollection(Font& font, Resource const& res) override; - void CreateTextFormat(TextLayout& layout) override; - void CreateTextLayout(TextLayout& layout) override; void CreateLineShape(Shape& shape, Point const& begin_pos, Point const& end_pos) override; diff --git a/src/kiwano/render/Font.h b/src/kiwano/render/Font.h index 39550468..d96ec02a 100644 --- a/src/kiwano/render/Font.h +++ b/src/kiwano/render/Font.h @@ -62,7 +62,11 @@ public: /// @brief 加载字体资源 bool Load(Resource const& resource); -#if defined(KGE_WIN32) + /// \~chinese + /// @brief 是否有效 + bool IsValid() const; + +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX public: ComPtr 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 Font::GetCollection() const { return collection_; diff --git a/src/kiwano/render/GifImage.cpp b/src/kiwano/render/GifImage.cpp index 0b574472..82256587 100644 --- a/src/kiwano/render/GifImage.cpp +++ b/src/kiwano/render/GifImage.cpp @@ -82,11 +82,6 @@ bool GifImage::Load(Resource const& res) return false; } -bool GifImage::IsValid() const -{ - return decoder_ != nullptr; -} - GifImage::Frame GifImage::GetFrame(uint32_t index) { Frame frame; @@ -94,7 +89,7 @@ GifImage::Frame GifImage::GetFrame(uint32_t index) return frame; } -#if defined(KGE_WIN32) +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX bool GifImage::GetGlobalMetadata() { HRESULT hr = decoder_ ? S_OK : E_FAIL; @@ -193,6 +188,14 @@ bool GifImage::GetGlobalMetadata() } return SUCCEEDED(hr); } + +#else + +bool GifImage::GetGlobalMetadata() +{ + return false; // not supported +} + #endif } // namespace kiwano diff --git a/src/kiwano/render/GifImage.h b/src/kiwano/render/GifImage.h index 3c4993c2..b62bd766 100644 --- a/src/kiwano/render/GifImage.h +++ b/src/kiwano/render/GifImage.h @@ -108,7 +108,7 @@ private: uint32_t width_in_pixels_; uint32_t height_in_pixels_; -#if defined(KGE_WIN32) +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX public: ComPtr GetDecoder() const; @@ -141,7 +141,16 @@ inline uint32_t GifImage::GetFramesCount() const 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 GifImage::GetDecoder() const { return decoder_; diff --git a/src/kiwano/render/Layer.h b/src/kiwano/render/Layer.h index 1619d795..ec3ff63a 100644 --- a/src/kiwano/render/Layer.h +++ b/src/kiwano/render/Layer.h @@ -80,7 +80,7 @@ private: ShapePtr mask_; Matrix3x2 mask_transform_; -#if defined(KGE_WIN32) +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX public: ComPtr GetLayer() const; @@ -95,7 +95,11 @@ private: inline bool Layer::IsValid() const { +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX return layer_ != nullptr; +#else + return false; // not supported +#endif } inline Rect const& Layer::GetClipRect() const @@ -138,7 +142,7 @@ inline void Layer::SetMaskTransform(Matrix3x2 const& matrix) mask_transform_ = matrix; } -#if defined(KGE_WIN32) +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX inline ComPtr Layer::GetLayer() const { return layer_; diff --git a/src/kiwano/render/Renderer.h b/src/kiwano/render/Renderer.h index cfe67cc1..fcf8c3c2 100644 --- a/src/kiwano/render/Renderer.h +++ b/src/kiwano/render/Renderer.h @@ -113,12 +113,6 @@ public: /// @throw std::system_error 创建失败时抛出 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 /// @brief 创建文字布局内部资源 /// @param[out] layout 字体布局 diff --git a/src/kiwano/render/Shape.cpp b/src/kiwano/render/Shape.cpp index 07a9ae35..5e55b6d2 100644 --- a/src/kiwano/render/Shape.cpp +++ b/src/kiwano/render/Shape.cpp @@ -27,13 +27,9 @@ namespace kiwano Shape::Shape() {} -bool Shape::IsValid() const -{ - return geo_ != nullptr; -} - Rect Shape::GetBoundingBox() const { +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX Rect bounds; if (geo_) { @@ -41,10 +37,14 @@ Rect Shape::GetBoundingBox() const geo_->GetBounds(nullptr, DX::ConvertToRectF(&bounds)); } return bounds; +#else + return Rect(); // not supported +#endif } Rect Shape::GetBoundingBox(Matrix3x2 const& transform) const { +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX Rect bounds; if (geo_) { @@ -52,10 +52,14 @@ Rect Shape::GetBoundingBox(Matrix3x2 const& transform) const geo_->GetBounds(DX::ConvertToMatrix3x2F(transform), DX::ConvertToRectF(&bounds)); } return bounds; +#else + return Rect(); // not supported +#endif } float Shape::GetLength() const { +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX float length = 0.f; if (geo_) { @@ -63,10 +67,14 @@ float Shape::GetLength() const geo_->ComputeLength(D2D1::Matrix3x2F::Identity(), &length); } return length; +#else + return 0.0f; // not supported +#endif } bool Shape::ComputePointAtLength(float length, Point& point, Vec2& tangent) const { +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX if (geo_) { 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 false; +#else + return false; // not supported +#endif } void Shape::Clear() { +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX geo_.reset(); +#else + return; // not supported +#endif } float Shape::ComputeArea() const { +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX if (!geo_) return 0.f; @@ -91,10 +107,14 @@ float Shape::ComputeArea() const // no matter it failed or not geo_->ComputeArea(D2D1::Matrix3x2F::Identity(), &area); return area; +#else + return 0.0f; // not supported +#endif } bool Shape::ContainsPoint(Point const& point, const Matrix3x2* transform) const { +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX if (!geo_) return false; @@ -103,6 +123,9 @@ bool Shape::ContainsPoint(Point const& point, const Matrix3x2* transform) const geo_->FillContainsPoint(DX::ConvertToPoint2F(point), DX::ConvertToMatrix3x2F(transform), D2D1_DEFAULT_FLATTENING_TOLERANCE, &ret); return !!ret; +#else + return false; // not supported +#endif } ShapePtr Shape::CreateLine(Point const& begin, Point const& end) diff --git a/src/kiwano/render/Shape.h b/src/kiwano/render/Shape.h index 94da7405..40a55a60 100644 --- a/src/kiwano/render/Shape.h +++ b/src/kiwano/render/Shape.h @@ -111,7 +111,7 @@ public: /// @brief 清除形状 void Clear(); -#if defined(KGE_WIN32) +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX public: ComPtr 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 Shape::GetGeometry() const { return geo_; diff --git a/src/kiwano/render/ShapeSink.cpp b/src/kiwano/render/ShapeSink.cpp index 91281e1e..e11cc76d 100644 --- a/src/kiwano/render/ShapeSink.cpp +++ b/src/kiwano/render/ShapeSink.cpp @@ -33,6 +33,7 @@ ShapeSink::~ShapeSink() void ShapeSink::Open() { +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX if (!IsOpened()) { path_geo_.reset(); @@ -40,10 +41,14 @@ void ShapeSink::Open() ThrowIfFailed(path_geo_->Open(&sink_), "Open ID2D1GeometrySink failed"); } +#else + return; // not supported +#endif } void ShapeSink::Close() { +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX if (IsOpened()) { ThrowIfFailed(sink_->Close(), "Close ID2D1GeometrySink failed"); @@ -52,11 +57,18 @@ void ShapeSink::Close() shape_ = new Shape; shape_->SetGeometry(path_geo_); +#else + return; // not supported +#endif } bool ShapeSink::IsOpened() const { +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX return sink_ != nullptr; +#else + return false; // not supported +#endif } ShapePtr ShapeSink::GetShape() @@ -72,6 +84,7 @@ ShapeSink& ShapeSink::AddShape(ShapePtr input, const Matrix3x2* input_matrix) Open(); } +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX if (input && input->IsValid()) { ComPtr geo = input->GetGeometry(); @@ -81,6 +94,9 @@ ShapeSink& ShapeSink::AddShape(ShapePtr input, const Matrix3x2* input_matrix) ThrowIfFailed(hr, "Get outline of ID2D1Geometry failed"); } return (*this); +#else + return (*this); // not supported +#endif } ShapeSink& ShapeSink::BeginPath(Point const& begin_pos) @@ -90,52 +106,80 @@ ShapeSink& ShapeSink::BeginPath(Point const& begin_pos) Open(); } +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX sink_->BeginFigure(DX::ConvertToPoint2F(begin_pos), D2D1_FIGURE_BEGIN_FILLED); +#else + // not supported +#endif return (*this); } ShapeSink& ShapeSink::EndPath(bool closed) { +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX KGE_ASSERT(sink_); sink_->EndFigure(closed ? D2D1_FIGURE_END_CLOSED : D2D1_FIGURE_END_OPEN); +#else + // not supported +#endif return (*this); } ShapeSink& ShapeSink::AddLine(Point const& point) { +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX KGE_ASSERT(sink_); sink_->AddLine(DX::ConvertToPoint2F(point)); +#else + // not supported +#endif return (*this); } ShapeSink& ShapeSink::AddLines(Vector const& points) { +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX KGE_ASSERT(sink_); sink_->AddLines(reinterpret_cast(&points[0]), static_cast(points.size())); +#else + // not supported +#endif return (*this); } ShapeSink& kiwano::ShapeSink::AddLines(const Point* points, size_t count) { +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX KGE_ASSERT(sink_); sink_->AddLines(reinterpret_cast(points), UINT32(count)); +#else + // not supported +#endif return (*this); } ShapeSink& ShapeSink::AddBezier(Point const& point1, Point const& point2, Point const& point3) { +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX KGE_ASSERT(sink_); sink_->AddBezier( D2D1::BezierSegment(DX::ConvertToPoint2F(point1), DX::ConvertToPoint2F(point2), DX::ConvertToPoint2F(point3))); +#else + // not supported +#endif return (*this); } 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_); sink_->AddArc(D2D1::ArcSegment(DX::ConvertToPoint2F(point), DX::ConvertToSizeF(radius), rotation, clockwise ? D2D1_SWEEP_DIRECTION_CLOCKWISE : D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE, is_small ? D2D1_ARC_SIZE_SMALL : D2D1_ARC_SIZE_LARGE)); +#else + // not supported +#endif return (*this); } @@ -146,6 +190,7 @@ ShapeSink& ShapeSink::Combine(ShapePtr shape_a, ShapePtr shape_b, CombineMode mo Open(); } +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX if (shape_a && shape_b) { ComPtr 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()); ThrowIfFailed(hr, "Combine ID2D1Geometry failed"); } +#else + // not supported +#endif return (*this); } @@ -162,7 +210,11 @@ void ShapeSink::Clear() { Close(); +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX path_geo_.reset(); +#else + // not supported +#endif } } // namespace kiwano diff --git a/src/kiwano/render/ShapeSink.h b/src/kiwano/render/ShapeSink.h index f56963d4..b40a5ae3 100644 --- a/src/kiwano/render/ShapeSink.h +++ b/src/kiwano/render/ShapeSink.h @@ -130,9 +130,9 @@ public: void Clear(); private: - ShapePtr shape_; + ShapePtr shape_; -#if defined(KGE_WIN32) +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX public: ComPtr GetPathGeometry() const; @@ -150,7 +150,7 @@ private: /** @} */ -#if defined(KGE_WIN32) +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX inline ComPtr ShapeSink::GetPathGeometry() const { return path_geo_; diff --git a/src/kiwano/render/StrokeStyle.cpp b/src/kiwano/render/StrokeStyle.cpp index 90b03f47..e188f732 100644 --- a/src/kiwano/render/StrokeStyle.cpp +++ b/src/kiwano/render/StrokeStyle.cpp @@ -112,6 +112,7 @@ void StrokeStyle::SetDashStyle(const float* dash_array, size_t dash_size) style_.reset(); } +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX ComPtr StrokeStyle::GetStrokeStyle() const { StrokeStyle& self = const_cast(*this); @@ -122,5 +123,6 @@ ComPtr StrokeStyle::GetStrokeStyle() const dash_offset_); return style_; } +#endif } // namespace kiwano diff --git a/src/kiwano/render/StrokeStyle.h b/src/kiwano/render/StrokeStyle.h index 31fee359..99b300cc 100644 --- a/src/kiwano/render/StrokeStyle.h +++ b/src/kiwano/render/StrokeStyle.h @@ -170,7 +170,7 @@ private: float dash_offset_; Vector dash_array_; -#if defined(KGE_WIN32) +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX public: ComPtr GetStrokeStyle() const; @@ -221,12 +221,16 @@ inline void StrokeStyle::SetDashOffset(float dash_offset) style_.reset(); } -#if defined(KGE_WIN32) inline bool StrokeStyle::IsValid() const { +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX return style_ != nullptr; +#else + return false; // not supported +#endif } +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX inline void StrokeStyle::SetStrokeStyle(ComPtr style) { style_ = style; diff --git a/src/kiwano/render/TextLayout.cpp b/src/kiwano/render/TextLayout.cpp index cfcf4ef4..09b77838 100644 --- a/src/kiwano/render/TextLayout.cpp +++ b/src/kiwano/render/TextLayout.cpp @@ -33,31 +33,7 @@ void TextLayout::Update() if (!IsDirty()) return; - if (text_.empty()) - { - 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; + Renderer::GetInstance().CreateTextLayout(*this); } void TextLayout::SetText(const String& text) @@ -122,6 +98,7 @@ uint32_t TextLayout::GetLineCount() const // Force to update layout const_cast(this)->Update(); +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX if (text_layout_) { DWRITE_TEXT_METRICS metrics; @@ -130,6 +107,9 @@ uint32_t TextLayout::GetLineCount() const return metrics.lineCount; } } +#else + // not supported +#endif return 0; } @@ -138,6 +118,7 @@ Size TextLayout::GetLayoutSize() const // Force to update layout const_cast(this)->Update(); +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX if (text_layout_) { DWRITE_TEXT_METRICS metrics; @@ -147,6 +128,9 @@ Size TextLayout::GetLayoutSize() const : Size(metrics.width, metrics.height); } } +#else + // not supported +#endif return Size(); } @@ -154,6 +138,7 @@ void TextLayout::SetWrapWidth(float wrap_width) { style_.wrap_width = wrap_width; +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX if (text_layout_) { HRESULT hr = S_OK; @@ -185,12 +170,16 @@ void TextLayout::SetWrapWidth(float wrap_width) } ThrowIfFailed(hr, "Apply word wrapping to text layout failed"); } +#else + return; // not supported +#endif } void TextLayout::SetLineSpacing(float line_spacing) { style_.line_spacing = line_spacing; +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX if (text_layout_) { HRESULT hr = S_OK; @@ -204,17 +193,24 @@ void TextLayout::SetLineSpacing(float line_spacing) } ThrowIfFailed(hr, "Apply line spacing to text layout failed"); } +#else + return; // not supported +#endif } void TextLayout::SetAlignment(TextAlign align) { style_.alignment = align; +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX if (text_layout_) { HRESULT hr = text_layout_->SetTextAlignment(DWRITE_TEXT_ALIGNMENT(align)); 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) @@ -222,6 +218,7 @@ void TextLayout::SetUnderline(bool enable, uint32_t start, uint32_t length) // Force to update layout Update(); +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX HRESULT hr = text_layout_ ? S_OK : E_FAIL; 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 }); } 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) @@ -236,6 +236,7 @@ void TextLayout::SetStrikethrough(bool enable, uint32_t start, uint32_t length) // Force to update layout Update(); +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX HRESULT hr = text_layout_ ? S_OK : E_FAIL; 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 }); } ThrowIfFailed(hr, "Apply strikethrough style to text layout failed"); +#else + return; // not supported +#endif } } // namespace kiwano diff --git a/src/kiwano/render/TextLayout.h b/src/kiwano/render/TextLayout.h index 1a601db7..b4954260 100644 --- a/src/kiwano/render/TextLayout.h +++ b/src/kiwano/render/TextLayout.h @@ -165,7 +165,7 @@ private: String text_; TextStyle style_; -#if defined(KGE_WIN32) +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX public: ComPtr GetTextFormat() const; @@ -185,7 +185,11 @@ private: inline bool TextLayout::IsValid() const { +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX return text_layout_ != nullptr; +#else + return false; // not supported +#endif } inline bool TextLayout::IsDirty() const @@ -243,7 +247,7 @@ inline void TextLayout::SetOutlineStroke(StrokeStylePtr outline_stroke) style_.outline_stroke = outline_stroke; } -#if defined(KGE_WIN32) +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX inline ComPtr TextLayout::GetTextFormat() const { return text_format_; diff --git a/src/kiwano/render/Texture.cpp b/src/kiwano/render/Texture.cpp index 4e44ed2f..44de3671 100644 --- a/src/kiwano/render/Texture.cpp +++ b/src/kiwano/render/Texture.cpp @@ -67,65 +67,34 @@ bool Texture::Load(Resource const& res) return IsValid(); } -bool Texture::IsValid() const -{ - return bitmap_ != nullptr; -} - float Texture::GetWidth() const { - if (bitmap_) - { - return bitmap_->GetSize().width; - } - return 0; + return size_.x; } float Texture::GetHeight() const { - if (bitmap_) - { - return bitmap_->GetSize().height; - } - return 0; + return size_.y; } Size Texture::GetSize() const { - if (bitmap_) - { - auto bitmap_size = bitmap_->GetSize(); - return Size{ bitmap_size.width, bitmap_size.height }; - } - return Size{}; + return size_; } uint32_t Texture::GetWidthInPixels() const { - if (bitmap_) - { - return bitmap_->GetPixelSize().width; - } - return 0; + return size_in_pixels_.x; } uint32_t Texture::GetHeightInPixels() const { - if (bitmap_) - { - return bitmap_->GetPixelSize().height; - } - return 0; + return size_in_pixels_.y; } math::Vec2T Texture::GetSizeInPixels() const { - if (bitmap_) - { - auto bitmap_size = bitmap_->GetPixelSize(); - return math::Vec2T{ bitmap_size.width, bitmap_size.height }; - } - return math::Vec2T{}; + return size_in_pixels_; } InterpolationMode Texture::GetBitmapInterpolationMode() const @@ -135,16 +104,21 @@ InterpolationMode Texture::GetBitmapInterpolationMode() const void Texture::CopyFrom(TexturePtr copy_from) { +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX if (IsValid() && copy_from) { HRESULT hr = bitmap_->CopyFromBitmap(nullptr, copy_from->GetBitmap().get(), nullptr); 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) { +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX if (IsValid() && copy_from) { 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"); } +#else + return; // not supported +#endif } void Texture::SetInterpolationMode(InterpolationMode mode) @@ -180,16 +157,4 @@ InterpolationMode Texture::GetDefaultInterpolationMode() return default_interpolation_mode_; } -#if defined(KGE_WIN32) -ComPtr Texture::GetBitmap() const -{ - return bitmap_; -} - -void Texture::SetBitmap(ComPtr bitmap) -{ - bitmap_ = bitmap; -} -#endif - } // namespace kiwano diff --git a/src/kiwano/render/Texture.h b/src/kiwano/render/Texture.h index 53dc6dd4..7d8fbf1b 100644 --- a/src/kiwano/render/Texture.h +++ b/src/kiwano/render/Texture.h @@ -132,7 +132,7 @@ private: static InterpolationMode default_interpolation_mode_; -#if defined(KGE_WIN32) +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX public: /// \~chinese /// @brief 获取源位图 @@ -143,10 +143,47 @@ public: void SetBitmap(ComPtr bitmap); private: - ComPtr bitmap_; + ComPtr bitmap_; + Size size_; + math::Vec2T size_in_pixels_; #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 Texture::GetBitmap() const +{ + return bitmap_; +} + +inline void Texture::SetBitmap(ComPtr 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