From 06d1d0442276a05b6caad6e3468f4afb1e8ee5df Mon Sep 17 00:00:00 2001 From: crupest Date: Sun, 28 Jun 2020 00:03:11 +0800 Subject: ... --- include/cru/win/Exception.hpp | 52 +++++++++ include/cru/win/String.hpp | 107 ++++++++++++++++++ include/cru/win/exception.hpp | 52 --------- include/cru/win/graph/direct/Brush.hpp | 39 +++++++ include/cru/win/graph/direct/Exception.hpp | 7 ++ include/cru/win/graph/direct/Factory.hpp | 58 ++++++++++ include/cru/win/graph/direct/Font.hpp | 32 ++++++ include/cru/win/graph/direct/Geometry.hpp | 57 ++++++++++ include/cru/win/graph/direct/Painter.hpp | 60 ++++++++++ include/cru/win/graph/direct/Resource.hpp | 49 ++++++++ include/cru/win/graph/direct/brush.hpp | 39 ------- include/cru/win/graph/direct/exception.hpp | 7 -- include/cru/win/graph/direct/factory.hpp | 58 ---------- include/cru/win/graph/direct/font.hpp | 32 ------ include/cru/win/graph/direct/geometry.hpp | 57 ---------- include/cru/win/graph/direct/painter.hpp | 60 ---------- include/cru/win/graph/direct/resource.hpp | 49 -------- include/cru/win/native/Base.hpp | 19 ++++ include/cru/win/native/Cursor.hpp | 47 ++++++++ include/cru/win/native/Exception.hpp | 7 ++ include/cru/win/native/Keyboard.hpp | 9 ++ include/cru/win/native/Resource.hpp | 23 ++++ include/cru/win/native/Window.hpp | 174 +++++++++++++++++++++++++++++ include/cru/win/native/base.hpp | 19 ---- include/cru/win/native/cursor.hpp | 47 -------- include/cru/win/native/exception.hpp | 7 -- include/cru/win/native/keyboard.hpp | 9 -- include/cru/win/native/resource.hpp | 23 ---- include/cru/win/native/window.hpp | 174 ----------------------------- include/cru/win/string.hpp | 107 ------------------ 30 files changed, 740 insertions(+), 740 deletions(-) create mode 100644 include/cru/win/Exception.hpp create mode 100644 include/cru/win/String.hpp delete mode 100644 include/cru/win/exception.hpp create mode 100644 include/cru/win/graph/direct/Brush.hpp create mode 100644 include/cru/win/graph/direct/Exception.hpp create mode 100644 include/cru/win/graph/direct/Factory.hpp create mode 100644 include/cru/win/graph/direct/Font.hpp create mode 100644 include/cru/win/graph/direct/Geometry.hpp create mode 100644 include/cru/win/graph/direct/Painter.hpp create mode 100644 include/cru/win/graph/direct/Resource.hpp delete mode 100644 include/cru/win/graph/direct/brush.hpp delete mode 100644 include/cru/win/graph/direct/exception.hpp delete mode 100644 include/cru/win/graph/direct/factory.hpp delete mode 100644 include/cru/win/graph/direct/font.hpp delete mode 100644 include/cru/win/graph/direct/geometry.hpp delete mode 100644 include/cru/win/graph/direct/painter.hpp delete mode 100644 include/cru/win/graph/direct/resource.hpp create mode 100644 include/cru/win/native/Base.hpp create mode 100644 include/cru/win/native/Cursor.hpp create mode 100644 include/cru/win/native/Exception.hpp create mode 100644 include/cru/win/native/Keyboard.hpp create mode 100644 include/cru/win/native/Resource.hpp create mode 100644 include/cru/win/native/Window.hpp delete mode 100644 include/cru/win/native/base.hpp delete mode 100644 include/cru/win/native/cursor.hpp delete mode 100644 include/cru/win/native/exception.hpp delete mode 100644 include/cru/win/native/keyboard.hpp delete mode 100644 include/cru/win/native/resource.hpp delete mode 100644 include/cru/win/native/window.hpp delete mode 100644 include/cru/win/string.hpp (limited to 'include/cru/win') diff --git a/include/cru/win/Exception.hpp b/include/cru/win/Exception.hpp new file mode 100644 index 00000000..234aea69 --- /dev/null +++ b/include/cru/win/Exception.hpp @@ -0,0 +1,52 @@ +#pragma once +#include "WinPreConfig.hpp" + +#include "cru/platform/Exception.hpp" + +#include +#include + +namespace cru::platform::win { +class HResultError : public platform::PlatformException { + public: + explicit HResultError(HRESULT h_result); + explicit HResultError(HRESULT h_result, const std::string_view& message); + + CRU_DEFAULT_COPY(HResultError) + CRU_DEFAULT_MOVE(HResultError) + + ~HResultError() override = default; + + HRESULT GetHResult() const { return h_result_; } + + private: + HRESULT h_result_; +}; + +inline void ThrowIfFailed(const HRESULT h_result) { + if (FAILED(h_result)) throw HResultError(h_result); +} + +inline void ThrowIfFailed(const HRESULT h_result, + const std::string_view& message) { + if (FAILED(h_result)) throw HResultError(h_result, message); +} + +class Win32Error : public platform::PlatformException { + public: + // ::GetLastError is automatically called to get the error code. + // The same as Win32Error(::GetLastError(), message) + explicit Win32Error(const std::string_view& message); + Win32Error(DWORD error_code, const std::string_view& message); + + CRU_DEFAULT_COPY(Win32Error) + CRU_DEFAULT_MOVE(Win32Error) + + ~Win32Error() override = default; + + DWORD GetErrorCode() const { return error_code_; } + + private: + DWORD error_code_; +}; +} // namespace cru::platform::win diff --git a/include/cru/win/String.hpp b/include/cru/win/String.hpp new file mode 100644 index 00000000..3d68cff7 --- /dev/null +++ b/include/cru/win/String.hpp @@ -0,0 +1,107 @@ +/* +Because the text encoding problem on Windows, here I write some functions +related to text encoding. The utf-8 and utf-16 conversion function is provided +by win32 api. However win32 api does not provide any function about charactor +iteration or index by code point. (At least I haven't found.) I don't use icu +because it is not easy to build it on Windows and the bundled version in Windows +(https://docs.microsoft.com/en-us/windows/win32/intl/international-components-for-unicode--icu-) +is only available after Windows 10 Creators Update. + +Luckily, both utf-8 and utf-16 encoding are easy to learn and program with if we +only do simple iteration rather than do much sophisticated work about +complicated error situations. (And I learn the internal of the encoding by the +way.) +*/ + +#pragma once +#include "WinPreConfig.hpp" + +#include "cru/common/Base.hpp" + +#include +#include +#include +#include + +namespace cru::platform::win { +std::string ToUtf8String(const std::wstring_view& string); +std::wstring ToUtf16String(const std::string_view& string); + +inline bool IsSurrogatePair(wchar_t c) { return c >= 0xD800 && c <= 0xDFFF; } + +inline bool IsSurrogatePairLeading(wchar_t c) { + return c >= 0xD800 && c <= 0xDBFF; +} + +inline bool IsSurrogatePairTrailing(wchar_t c) { + return c >= 0xDC00 && c <= 0xDFFF; +} + +using CodePoint = std::int32_t; +constexpr CodePoint k_code_point_end = -1; + +class TextEncodeException : public std::runtime_error { + public: + using runtime_error::runtime_error; +}; + +class Utf8Iterator : public Object { + public: + Utf8Iterator(const std::string_view& string) : string_(string) {} + + CRU_DEFAULT_COPY(Utf8Iterator) + CRU_DEFAULT_MOVE(Utf8Iterator) + + ~Utf8Iterator() = default; + + public: + void SetToHead() { position_ = 0; } + + // Advance current position and get next code point. Return k_code_point_end + // if there is no next code unit(point). Throw TextEncodeException if decoding + // fails. + CodePoint Next(); + + int CurrentPosition() const { return this->position_; } + + private: + std::string_view string_; + int position_ = 0; +}; + +class Utf16Iterator : public Object { + static_assert( + sizeof(wchar_t) == 2, + "Emmm, according to my knowledge, wchar_t should be 2-length on " + "Windows. If not, Utf16 will be broken."); + + public: + Utf16Iterator(const std::wstring_view& string) : string_(string) {} + + CRU_DEFAULT_COPY(Utf16Iterator) + CRU_DEFAULT_MOVE(Utf16Iterator) + + ~Utf16Iterator() = default; + + public: + void SetToHead() { position_ = 0; } + + // Advance current position and get next code point. Return k_code_point_end + // if there is no next code unit(point). Throw TextEncodeException if decoding + // fails. + CodePoint Next(); + + int CurrentPosition() const { return this->position_; } + + private: + std::wstring_view string_; + int position_ = 0; +}; + +int IndexUtf8ToUtf16(const std::string_view& utf8_string, int utf8_index, + const std::wstring_view& utf16_string); + +int IndexUtf16ToUtf8(const std::wstring_view& utf16_string, int utf16_index, + const std::string_view& utf8_string); + +} // namespace cru::platform::win diff --git a/include/cru/win/exception.hpp b/include/cru/win/exception.hpp deleted file mode 100644 index 234aea69..00000000 --- a/include/cru/win/exception.hpp +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once -#include "WinPreConfig.hpp" - -#include "cru/platform/Exception.hpp" - -#include -#include - -namespace cru::platform::win { -class HResultError : public platform::PlatformException { - public: - explicit HResultError(HRESULT h_result); - explicit HResultError(HRESULT h_result, const std::string_view& message); - - CRU_DEFAULT_COPY(HResultError) - CRU_DEFAULT_MOVE(HResultError) - - ~HResultError() override = default; - - HRESULT GetHResult() const { return h_result_; } - - private: - HRESULT h_result_; -}; - -inline void ThrowIfFailed(const HRESULT h_result) { - if (FAILED(h_result)) throw HResultError(h_result); -} - -inline void ThrowIfFailed(const HRESULT h_result, - const std::string_view& message) { - if (FAILED(h_result)) throw HResultError(h_result, message); -} - -class Win32Error : public platform::PlatformException { - public: - // ::GetLastError is automatically called to get the error code. - // The same as Win32Error(::GetLastError(), message) - explicit Win32Error(const std::string_view& message); - Win32Error(DWORD error_code, const std::string_view& message); - - CRU_DEFAULT_COPY(Win32Error) - CRU_DEFAULT_MOVE(Win32Error) - - ~Win32Error() override = default; - - DWORD GetErrorCode() const { return error_code_; } - - private: - DWORD error_code_; -}; -} // namespace cru::platform::win diff --git a/include/cru/win/graph/direct/Brush.hpp b/include/cru/win/graph/direct/Brush.hpp new file mode 100644 index 00000000..df1debe3 --- /dev/null +++ b/include/cru/win/graph/direct/Brush.hpp @@ -0,0 +1,39 @@ +#pragma once +#include "ComResource.hpp" +#include "Resource.hpp" + +#include "cru/platform/graph/Brush.hpp" + +namespace cru::platform::graph::win::direct { +struct ID2DBrush : virtual IBrush { + virtual ID2D1Brush* GetD2DBrushInterface() const = 0; +}; + +class D2DSolidColorBrush : public DirectGraphResource, + public virtual ISolidColorBrush, + public virtual ID2DBrush, + public virtual IComResource { + public: + explicit D2DSolidColorBrush(DirectGraphFactory* factory); + + CRU_DELETE_COPY(D2DSolidColorBrush) + CRU_DELETE_MOVE(D2DSolidColorBrush) + + ~D2DSolidColorBrush() override = default; + + public: + Color GetColor() override { return color_; } + void SetColor(const Color& color) override; + + ID2D1Brush* GetD2DBrushInterface() const override { return brush_.Get(); } + + ID2D1SolidColorBrush* GetComInterface() const override { + return brush_.Get(); + } + + private: + Color color_ = colors::black; + + Microsoft::WRL::ComPtr brush_; +}; +} // namespace cru::platform::graph::win::direct diff --git a/include/cru/win/graph/direct/Exception.hpp b/include/cru/win/graph/direct/Exception.hpp new file mode 100644 index 00000000..8b62e8fa --- /dev/null +++ b/include/cru/win/graph/direct/Exception.hpp @@ -0,0 +1,7 @@ +#pragma once +#include "../../Exception.hpp" + +namespace cru::platform::graph::win::direct { +using platform::win::HResultError; +using platform::win::ThrowIfFailed; +} // namespace cru::platform::graph::win::direct \ No newline at end of file diff --git a/include/cru/win/graph/direct/Factory.hpp b/include/cru/win/graph/direct/Factory.hpp new file mode 100644 index 00000000..763d4b2b --- /dev/null +++ b/include/cru/win/graph/direct/Factory.hpp @@ -0,0 +1,58 @@ +#pragma once +#include "Resource.hpp" + +#include "cru/platform/graph/Factory.hpp" + +namespace cru::platform::graph::win::direct { +class DirectGraphFactory : public DirectResource, public virtual IGraphFactory { + public: + DirectGraphFactory(); + + CRU_DELETE_COPY(DirectGraphFactory) + CRU_DELETE_MOVE(DirectGraphFactory) + + ~DirectGraphFactory() override; + + public: + ID3D11Device* GetD3D11Device() const { return d3d11_device_.Get(); } + ID2D1Factory1* GetD2D1Factory() const { return d2d1_factory_.Get(); } + ID2D1Device* GetD2D1Device() const { return d2d1_device_.Get(); } + IDXGIFactory2* GetDxgiFactory() const { return dxgi_factory_.Get(); } + IDWriteFactory* GetDWriteFactory() const { return dwrite_factory_.Get(); } + IDWriteFontCollection* GetSystemFontCollection() const { + return dwrite_system_font_collection_.Get(); + } + + public: + Microsoft::WRL::ComPtr CreateD2D1DeviceContext(); + + // This context should only be used to create graphic resources like brush. + // Because graphic resources can be shared if they are created in the same + // device. + ID2D1DeviceContext* GetDefaultD2D1DeviceContext() { + return d2d1_device_context_.Get(); + } + + public: + std::unique_ptr CreateSolidColorBrush() override; + + std::unique_ptr CreateGeometryBuilder() override; + + std::unique_ptr CreateFont(const std::string_view& font_family, + float font_size) override; + + std::unique_ptr CreateTextLayout(std::shared_ptr font, + std::string text) override; + + private: + Microsoft::WRL::ComPtr d3d11_device_; + // ID2D1Factory1 is a interface only available in Windows 8 and Windows 7 with + // update. It is d2d v1.1. + Microsoft::WRL::ComPtr d2d1_factory_; + Microsoft::WRL::ComPtr d2d1_device_; + Microsoft::WRL::ComPtr d2d1_device_context_; + Microsoft::WRL::ComPtr dxgi_factory_; + Microsoft::WRL::ComPtr dwrite_factory_; + Microsoft::WRL::ComPtr dwrite_system_font_collection_; +}; +} // namespace cru::platform::graph::win::direct diff --git a/include/cru/win/graph/direct/Font.hpp b/include/cru/win/graph/direct/Font.hpp new file mode 100644 index 00000000..ecf9fd81 --- /dev/null +++ b/include/cru/win/graph/direct/Font.hpp @@ -0,0 +1,32 @@ +#pragma once +#include "ComResource.hpp" +#include "Resource.hpp" + +#include "cru/platform/graph/Font.hpp" + +#include + +namespace cru::platform::graph::win::direct { +class DWriteFont : public DirectGraphResource, + public virtual IFont, + public virtual IComResource { + public: + DWriteFont(DirectGraphFactory* factory, const std::string_view& font_family, + float font_size); + + CRU_DELETE_COPY(DWriteFont) + CRU_DELETE_MOVE(DWriteFont) + + ~DWriteFont() override = default; + + public: + IDWriteTextFormat* GetComInterface() const override { + return text_format_.Get(); + } + + float GetFontSize() override; + + private: + Microsoft::WRL::ComPtr text_format_; +}; +} // namespace cru::platform::graph::win::direct diff --git a/include/cru/win/graph/direct/Geometry.hpp b/include/cru/win/graph/direct/Geometry.hpp new file mode 100644 index 00000000..87987d3e --- /dev/null +++ b/include/cru/win/graph/direct/Geometry.hpp @@ -0,0 +1,57 @@ +#pragma once +#include "ComResource.hpp" +#include "Resource.hpp" + +#include "cru/platform/graph/Geometry.hpp" + +namespace cru::platform::graph::win::direct { +class D2DGeometryBuilder : public DirectGraphResource, + public virtual IGeometryBuilder { + public: + explicit D2DGeometryBuilder(DirectGraphFactory* factory); + + CRU_DELETE_COPY(D2DGeometryBuilder) + CRU_DELETE_MOVE(D2DGeometryBuilder) + + ~D2DGeometryBuilder() override = default; + + public: + void BeginFigure(const Point& point) override; + void LineTo(const Point& point) override; + void QuadraticBezierTo(const Point& control_point, + const Point& end_point) override; + void CloseFigure(bool close) override; + + std::unique_ptr Build() override; + + private: + bool IsValid() { return geometry_ != nullptr; } + void CheckValidation(); + + private: + Microsoft::WRL::ComPtr geometry_; + Microsoft::WRL::ComPtr geometry_sink_; +}; + +class D2DGeometry : public DirectGraphResource, + public virtual IGeometry, + public IComResource { + public: + D2DGeometry(DirectGraphFactory* factory, + Microsoft::WRL::ComPtr geometry); + + CRU_DELETE_COPY(D2DGeometry) + CRU_DELETE_MOVE(D2DGeometry) + + ~D2DGeometry() override = default; + + public: + ID2D1Geometry* GetComInterface() const override { return geometry_.Get(); } + + public: + bool FillContains(const Point& point) override; + + private: + Microsoft::WRL::ComPtr geometry_; +}; +} // namespace cru::platform::graph::win::direct diff --git a/include/cru/win/graph/direct/Painter.hpp b/include/cru/win/graph/direct/Painter.hpp new file mode 100644 index 00000000..a50f962d --- /dev/null +++ b/include/cru/win/graph/direct/Painter.hpp @@ -0,0 +1,60 @@ +#pragma once +#include "ComResource.hpp" +#include "Resource.hpp" + +#include "cru/platform/graph/Painter.hpp" + +#include + +namespace cru::platform::graph::win::direct { +class D2DPainter : public DirectResource, + public virtual IPainter, + public virtual IComResource { + public: + explicit D2DPainter(ID2D1RenderTarget* render_target); + + CRU_DELETE_COPY(D2DPainter) + CRU_DELETE_MOVE(D2DPainter) + + ~D2DPainter() override = default; + + public: + ID2D1RenderTarget* GetComInterface() const override { return render_target_; } + + public: + Matrix GetTransform() override; + void SetTransform(const platform::Matrix& matrix) override; + + void Clear(const Color& color) override; + + void StrokeRectangle(const Rect& rectangle, IBrush* brush, + float width) override; + void FillRectangle(const Rect& rectangle, IBrush* brush) override; + + void StrokeGeometry(IGeometry* geometry, IBrush* brush, float width) override; + void FillGeometry(IGeometry* geometry, IBrush* brush) override; + + void DrawText(const Point& offset, ITextLayout* text_layout, + IBrush* brush) override; + + void PushLayer(const Rect& bounds) override; + + void PopLayer() override; + + void EndDraw() override final; + + protected: + virtual void DoEndDraw() = 0; + + private: + bool IsValid() { return is_drawing_; } + void CheckValidation(); + + private: + ID2D1RenderTarget* render_target_; + + std::vector> layers_; + + bool is_drawing_ = true; +}; +} // namespace cru::platform::graph::win::direct diff --git a/include/cru/win/graph/direct/Resource.hpp b/include/cru/win/graph/direct/Resource.hpp new file mode 100644 index 00000000..d0a30dbd --- /dev/null +++ b/include/cru/win/graph/direct/Resource.hpp @@ -0,0 +1,49 @@ +#pragma once +#include "../../WinPreConfig.hpp" + +#include "cru/platform/graph/Resource.hpp" + +#include + +namespace cru::platform::graph::win::direct { +class DirectGraphFactory; + +class DirectResource : public Object, public virtual INativeResource { + public: + static constexpr std::string_view k_platform_id = "Windows Direct"; + + protected: + DirectResource() = default; + + public: + CRU_DELETE_COPY(DirectResource) + CRU_DELETE_MOVE(DirectResource) + + ~DirectResource() override = default; + + public: + std::string_view GetPlatformId() const final { return k_platform_id; } +}; + +class DirectGraphResource : public DirectResource, + public virtual IGraphResource { + protected: + // Param factory can't be null. + explicit DirectGraphResource(DirectGraphFactory* factory); + + public: + CRU_DELETE_COPY(DirectGraphResource) + CRU_DELETE_MOVE(DirectGraphResource) + + ~DirectGraphResource() override = default; + + public: + IGraphFactory* GetGraphFactory() final; + + public: + DirectGraphFactory* GetDirectFactory() const { return factory_; } + + private: + DirectGraphFactory* factory_; +}; +} // namespace cru::platform::graph::win::direct diff --git a/include/cru/win/graph/direct/brush.hpp b/include/cru/win/graph/direct/brush.hpp deleted file mode 100644 index df1debe3..00000000 --- a/include/cru/win/graph/direct/brush.hpp +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once -#include "ComResource.hpp" -#include "Resource.hpp" - -#include "cru/platform/graph/Brush.hpp" - -namespace cru::platform::graph::win::direct { -struct ID2DBrush : virtual IBrush { - virtual ID2D1Brush* GetD2DBrushInterface() const = 0; -}; - -class D2DSolidColorBrush : public DirectGraphResource, - public virtual ISolidColorBrush, - public virtual ID2DBrush, - public virtual IComResource { - public: - explicit D2DSolidColorBrush(DirectGraphFactory* factory); - - CRU_DELETE_COPY(D2DSolidColorBrush) - CRU_DELETE_MOVE(D2DSolidColorBrush) - - ~D2DSolidColorBrush() override = default; - - public: - Color GetColor() override { return color_; } - void SetColor(const Color& color) override; - - ID2D1Brush* GetD2DBrushInterface() const override { return brush_.Get(); } - - ID2D1SolidColorBrush* GetComInterface() const override { - return brush_.Get(); - } - - private: - Color color_ = colors::black; - - Microsoft::WRL::ComPtr brush_; -}; -} // namespace cru::platform::graph::win::direct diff --git a/include/cru/win/graph/direct/exception.hpp b/include/cru/win/graph/direct/exception.hpp deleted file mode 100644 index 8b62e8fa..00000000 --- a/include/cru/win/graph/direct/exception.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once -#include "../../Exception.hpp" - -namespace cru::platform::graph::win::direct { -using platform::win::HResultError; -using platform::win::ThrowIfFailed; -} // namespace cru::platform::graph::win::direct \ No newline at end of file diff --git a/include/cru/win/graph/direct/factory.hpp b/include/cru/win/graph/direct/factory.hpp deleted file mode 100644 index 763d4b2b..00000000 --- a/include/cru/win/graph/direct/factory.hpp +++ /dev/null @@ -1,58 +0,0 @@ -#pragma once -#include "Resource.hpp" - -#include "cru/platform/graph/Factory.hpp" - -namespace cru::platform::graph::win::direct { -class DirectGraphFactory : public DirectResource, public virtual IGraphFactory { - public: - DirectGraphFactory(); - - CRU_DELETE_COPY(DirectGraphFactory) - CRU_DELETE_MOVE(DirectGraphFactory) - - ~DirectGraphFactory() override; - - public: - ID3D11Device* GetD3D11Device() const { return d3d11_device_.Get(); } - ID2D1Factory1* GetD2D1Factory() const { return d2d1_factory_.Get(); } - ID2D1Device* GetD2D1Device() const { return d2d1_device_.Get(); } - IDXGIFactory2* GetDxgiFactory() const { return dxgi_factory_.Get(); } - IDWriteFactory* GetDWriteFactory() const { return dwrite_factory_.Get(); } - IDWriteFontCollection* GetSystemFontCollection() const { - return dwrite_system_font_collection_.Get(); - } - - public: - Microsoft::WRL::ComPtr CreateD2D1DeviceContext(); - - // This context should only be used to create graphic resources like brush. - // Because graphic resources can be shared if they are created in the same - // device. - ID2D1DeviceContext* GetDefaultD2D1DeviceContext() { - return d2d1_device_context_.Get(); - } - - public: - std::unique_ptr CreateSolidColorBrush() override; - - std::unique_ptr CreateGeometryBuilder() override; - - std::unique_ptr CreateFont(const std::string_view& font_family, - float font_size) override; - - std::unique_ptr CreateTextLayout(std::shared_ptr font, - std::string text) override; - - private: - Microsoft::WRL::ComPtr d3d11_device_; - // ID2D1Factory1 is a interface only available in Windows 8 and Windows 7 with - // update. It is d2d v1.1. - Microsoft::WRL::ComPtr d2d1_factory_; - Microsoft::WRL::ComPtr d2d1_device_; - Microsoft::WRL::ComPtr d2d1_device_context_; - Microsoft::WRL::ComPtr dxgi_factory_; - Microsoft::WRL::ComPtr dwrite_factory_; - Microsoft::WRL::ComPtr dwrite_system_font_collection_; -}; -} // namespace cru::platform::graph::win::direct diff --git a/include/cru/win/graph/direct/font.hpp b/include/cru/win/graph/direct/font.hpp deleted file mode 100644 index ecf9fd81..00000000 --- a/include/cru/win/graph/direct/font.hpp +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once -#include "ComResource.hpp" -#include "Resource.hpp" - -#include "cru/platform/graph/Font.hpp" - -#include - -namespace cru::platform::graph::win::direct { -class DWriteFont : public DirectGraphResource, - public virtual IFont, - public virtual IComResource { - public: - DWriteFont(DirectGraphFactory* factory, const std::string_view& font_family, - float font_size); - - CRU_DELETE_COPY(DWriteFont) - CRU_DELETE_MOVE(DWriteFont) - - ~DWriteFont() override = default; - - public: - IDWriteTextFormat* GetComInterface() const override { - return text_format_.Get(); - } - - float GetFontSize() override; - - private: - Microsoft::WRL::ComPtr text_format_; -}; -} // namespace cru::platform::graph::win::direct diff --git a/include/cru/win/graph/direct/geometry.hpp b/include/cru/win/graph/direct/geometry.hpp deleted file mode 100644 index 87987d3e..00000000 --- a/include/cru/win/graph/direct/geometry.hpp +++ /dev/null @@ -1,57 +0,0 @@ -#pragma once -#include "ComResource.hpp" -#include "Resource.hpp" - -#include "cru/platform/graph/Geometry.hpp" - -namespace cru::platform::graph::win::direct { -class D2DGeometryBuilder : public DirectGraphResource, - public virtual IGeometryBuilder { - public: - explicit D2DGeometryBuilder(DirectGraphFactory* factory); - - CRU_DELETE_COPY(D2DGeometryBuilder) - CRU_DELETE_MOVE(D2DGeometryBuilder) - - ~D2DGeometryBuilder() override = default; - - public: - void BeginFigure(const Point& point) override; - void LineTo(const Point& point) override; - void QuadraticBezierTo(const Point& control_point, - const Point& end_point) override; - void CloseFigure(bool close) override; - - std::unique_ptr Build() override; - - private: - bool IsValid() { return geometry_ != nullptr; } - void CheckValidation(); - - private: - Microsoft::WRL::ComPtr geometry_; - Microsoft::WRL::ComPtr geometry_sink_; -}; - -class D2DGeometry : public DirectGraphResource, - public virtual IGeometry, - public IComResource { - public: - D2DGeometry(DirectGraphFactory* factory, - Microsoft::WRL::ComPtr geometry); - - CRU_DELETE_COPY(D2DGeometry) - CRU_DELETE_MOVE(D2DGeometry) - - ~D2DGeometry() override = default; - - public: - ID2D1Geometry* GetComInterface() const override { return geometry_.Get(); } - - public: - bool FillContains(const Point& point) override; - - private: - Microsoft::WRL::ComPtr geometry_; -}; -} // namespace cru::platform::graph::win::direct diff --git a/include/cru/win/graph/direct/painter.hpp b/include/cru/win/graph/direct/painter.hpp deleted file mode 100644 index a50f962d..00000000 --- a/include/cru/win/graph/direct/painter.hpp +++ /dev/null @@ -1,60 +0,0 @@ -#pragma once -#include "ComResource.hpp" -#include "Resource.hpp" - -#include "cru/platform/graph/Painter.hpp" - -#include - -namespace cru::platform::graph::win::direct { -class D2DPainter : public DirectResource, - public virtual IPainter, - public virtual IComResource { - public: - explicit D2DPainter(ID2D1RenderTarget* render_target); - - CRU_DELETE_COPY(D2DPainter) - CRU_DELETE_MOVE(D2DPainter) - - ~D2DPainter() override = default; - - public: - ID2D1RenderTarget* GetComInterface() const override { return render_target_; } - - public: - Matrix GetTransform() override; - void SetTransform(const platform::Matrix& matrix) override; - - void Clear(const Color& color) override; - - void StrokeRectangle(const Rect& rectangle, IBrush* brush, - float width) override; - void FillRectangle(const Rect& rectangle, IBrush* brush) override; - - void StrokeGeometry(IGeometry* geometry, IBrush* brush, float width) override; - void FillGeometry(IGeometry* geometry, IBrush* brush) override; - - void DrawText(const Point& offset, ITextLayout* text_layout, - IBrush* brush) override; - - void PushLayer(const Rect& bounds) override; - - void PopLayer() override; - - void EndDraw() override final; - - protected: - virtual void DoEndDraw() = 0; - - private: - bool IsValid() { return is_drawing_; } - void CheckValidation(); - - private: - ID2D1RenderTarget* render_target_; - - std::vector> layers_; - - bool is_drawing_ = true; -}; -} // namespace cru::platform::graph::win::direct diff --git a/include/cru/win/graph/direct/resource.hpp b/include/cru/win/graph/direct/resource.hpp deleted file mode 100644 index d0a30dbd..00000000 --- a/include/cru/win/graph/direct/resource.hpp +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once -#include "../../WinPreConfig.hpp" - -#include "cru/platform/graph/Resource.hpp" - -#include - -namespace cru::platform::graph::win::direct { -class DirectGraphFactory; - -class DirectResource : public Object, public virtual INativeResource { - public: - static constexpr std::string_view k_platform_id = "Windows Direct"; - - protected: - DirectResource() = default; - - public: - CRU_DELETE_COPY(DirectResource) - CRU_DELETE_MOVE(DirectResource) - - ~DirectResource() override = default; - - public: - std::string_view GetPlatformId() const final { return k_platform_id; } -}; - -class DirectGraphResource : public DirectResource, - public virtual IGraphResource { - protected: - // Param factory can't be null. - explicit DirectGraphResource(DirectGraphFactory* factory); - - public: - CRU_DELETE_COPY(DirectGraphResource) - CRU_DELETE_MOVE(DirectGraphResource) - - ~DirectGraphResource() override = default; - - public: - IGraphFactory* GetGraphFactory() final; - - public: - DirectGraphFactory* GetDirectFactory() const { return factory_; } - - private: - DirectGraphFactory* factory_; -}; -} // namespace cru::platform::graph::win::direct diff --git a/include/cru/win/native/Base.hpp b/include/cru/win/native/Base.hpp new file mode 100644 index 00000000..a50c6dd1 --- /dev/null +++ b/include/cru/win/native/Base.hpp @@ -0,0 +1,19 @@ +#pragma once +#include "../WinPreConfig.hpp" + +#include "cru/common/Base.hpp" + +namespace cru::platform::native::win { +class GodWindow; +class TimerManager; +class WinCursor; +class WinCursorManager; +class WindowClass; +class WindowManager; +class WindowRenderTarget; +class WinNativeWindow; +class WinNativeWindowResolver; +class WinUiApplication; +class WinInputMethodManager; +class WinInputMethodContextRef; +} // namespace cru::platform::native::win diff --git a/include/cru/win/native/Cursor.hpp b/include/cru/win/native/Cursor.hpp new file mode 100644 index 00000000..152374d8 --- /dev/null +++ b/include/cru/win/native/Cursor.hpp @@ -0,0 +1,47 @@ +#pragma once +#include "Resource.hpp" + +#include "cru/platform/native/Cursor.hpp" + +#include + +namespace cru::platform::native::win { +class WinCursor : public WinNativeResource, public virtual ICursor { + public: + WinCursor(HCURSOR handle, bool auto_destroy); + + CRU_DELETE_COPY(WinCursor) + CRU_DELETE_MOVE(WinCursor) + + ~WinCursor() override; + + public: + HCURSOR GetHandle() const { return handle_; } + + private: + HCURSOR handle_; + bool auto_destroy_; +}; + +class WinCursorManager : public WinNativeResource, + public virtual ICursorManager { + public: + WinCursorManager(); + + CRU_DELETE_COPY(WinCursorManager) + CRU_DELETE_MOVE(WinCursorManager) + + ~WinCursorManager() override = default; + + public: + std::shared_ptr GetSystemWinCursor(SystemCursorType type); + + std::shared_ptr GetSystemCursor(SystemCursorType type) override { + return std::static_pointer_cast(GetSystemWinCursor(type)); + } + + private: + std::shared_ptr sys_arrow_; + std::shared_ptr sys_hand_; +}; +} // namespace cru::platform::native::win diff --git a/include/cru/win/native/Exception.hpp b/include/cru/win/native/Exception.hpp new file mode 100644 index 00000000..6a5265c1 --- /dev/null +++ b/include/cru/win/native/Exception.hpp @@ -0,0 +1,7 @@ +#pragma once +#include "../Exception.hpp" + +namespace cru::platform::native::win { +using platform::win::Win32Error; +using platform::win::HResultError; +} // namespace cru::platform::native::win diff --git a/include/cru/win/native/Keyboard.hpp b/include/cru/win/native/Keyboard.hpp new file mode 100644 index 00000000..790e0015 --- /dev/null +++ b/include/cru/win/native/Keyboard.hpp @@ -0,0 +1,9 @@ +#pragma once +#include "Base.hpp" + +#include "cru/platform/native/Keyboard.hpp" + +namespace cru::platform::native::win { +KeyCode VirtualKeyToKeyCode(int virtual_key); +KeyModifier RetrieveKeyMofifier(); +} // namespace cru::platform::native::win diff --git a/include/cru/win/native/Resource.hpp b/include/cru/win/native/Resource.hpp new file mode 100644 index 00000000..7afaca0f --- /dev/null +++ b/include/cru/win/native/Resource.hpp @@ -0,0 +1,23 @@ +#pragma once +#include "Base.hpp" + +#include "cru/platform/Resource.hpp" + +namespace cru::platform::native::win { +class WinNativeResource : public Object, public virtual INativeResource { + public: + static constexpr std::string_view k_platform_id = "Windows"; + + protected: + WinNativeResource() = default; + + public: + CRU_DELETE_COPY(WinNativeResource) + CRU_DELETE_MOVE(WinNativeResource) + + ~WinNativeResource() override = default; + + public: + std::string_view GetPlatformId() const final { return k_platform_id; } +}; +} // namespace cru::platform::native::win diff --git a/include/cru/win/native/Window.hpp b/include/cru/win/native/Window.hpp new file mode 100644 index 00000000..80bee39e --- /dev/null +++ b/include/cru/win/native/Window.hpp @@ -0,0 +1,174 @@ +#pragma once +#include "Resource.hpp" + +#include "cru/platform/native/Window.hpp" +#include "WindowNativeMessageEventArgs.hpp" + +#include + +namespace cru::platform::native::win { +class WinNativeWindow : public WinNativeResource, public virtual INativeWindow { + public: + WinNativeWindow(WinUiApplication* application, WindowClass* window_class, + DWORD window_style, WinNativeWindow* parent); + + CRU_DELETE_COPY(WinNativeWindow) + CRU_DELETE_MOVE(WinNativeWindow) + + ~WinNativeWindow() override; + + public: + std::shared_ptr GetResolver() override { + return std::static_pointer_cast(resolver_); + } + + void Close() override; + + WinNativeWindow* GetParent() override { return parent_window_; } + + bool IsVisible() override; + void SetVisible(bool is_visible) override; + + Size GetClientSize() override; + void SetClientSize(const Size& size) override; + + // Get the rect of the window containing frame. + // The lefttop of the rect is relative to screen lefttop. + Rect GetWindowRect() override; + + // Set the rect of the window containing frame. + // The lefttop of the rect is relative to screen lefttop. + void SetWindowRect(const Rect& rect) override; + + Point GetMousePosition() override; + + bool CaptureMouse() override; + bool ReleaseMouse() override; + + void RequestRepaint() override; + std::unique_ptr BeginPaint() override; + + void SetCursor(std::shared_ptr cursor) override; + + IEvent* DestroyEvent() override { return &destroy_event_; } + IEvent* PaintEvent() override { return &paint_event_; } + IEvent* ResizeEvent() override { return &resize_event_; } + IEvent* FocusEvent() override { return &focus_event_; } + IEvent* MouseEnterLeaveEvent() override { + return &mouse_enter_leave_event_; + } + IEvent* MouseMoveEvent() override { return &mouse_move_event_; } + IEvent* MouseDownEvent() + override { + return &mouse_down_event_; + } + IEvent* MouseUpEvent() + override { + return &mouse_up_event_; + } + IEvent* KeyDownEvent() override { + return &key_down_event_; + } + IEvent* KeyUpEvent() override { + return &key_up_event_; + } + + IEvent* NativeMessageEvent() { + return &native_message_event_; + } + + // Get the handle of the window. Return null if window is invalid. + HWND GetWindowHandle() const { return hwnd_; } + + bool HandleNativeWindowMessage(HWND hwnd, UINT msg, WPARAM w_param, + LPARAM l_param, LRESULT* result); + + WindowRenderTarget* GetWindowRenderTarget() const { + return window_render_target_.get(); + } + + private: + // Get the client rect in pixel. + RECT GetClientRectPixel(); + + //*************** region: native messages *************** + + void OnDestroyInternal(); + void OnPaintInternal(); + void OnResizeInternal(int new_width, int new_height); + + void OnSetFocusInternal(); + void OnKillFocusInternal(); + + void OnMouseMoveInternal(POINT point); + void OnMouseLeaveInternal(); + void OnMouseDownInternal(platform::native::MouseButton button, POINT point); + void OnMouseUpInternal(platform::native::MouseButton button, POINT point); + + void OnMouseWheelInternal(short delta, POINT point); + void OnKeyDownInternal(int virtual_code); + void OnKeyUpInternal(int virtual_code); + + void OnActivatedInternal(); + void OnDeactivatedInternal(); + + private: + WinUiApplication* application_; + + // when delete is called first, it set this to true to indicate + // destroy message handler not to double delete this instance; + // when destroy handler is called first (by user action or method + // Close), it set this to true to indicate delete not call Close + // again. + bool sync_flag_ = false; + + std::shared_ptr resolver_; + + HWND hwnd_; + WinNativeWindow* parent_window_; + + bool has_focus_ = false; + bool is_mouse_in_ = false; + + std::unique_ptr window_render_target_; + + std::shared_ptr cursor_; + + Event destroy_event_; + Event paint_event_; + Event resize_event_; + Event focus_event_; + Event mouse_enter_leave_event_; + Event mouse_move_event_; + Event mouse_down_event_; + Event mouse_up_event_; + Event key_down_event_; + Event key_up_event_; + + Event native_message_event_; +}; + +class WinNativeWindowResolver : public WinNativeResource, + public virtual INativeWindowResolver { + friend WinNativeWindow::~WinNativeWindow(); + + public: + WinNativeWindowResolver(WinNativeWindow* window) : window_(window) {} + + CRU_DELETE_COPY(WinNativeWindowResolver) + CRU_DELETE_MOVE(WinNativeWindowResolver) + + ~WinNativeWindowResolver() override = default; + + public: + INativeWindow* Resolve() override { return window_; } + + private: + void Reset(); + + private: + WinNativeWindow* window_; +}; + +WinNativeWindow* Resolve(gsl::not_null resolver); +} // namespace cru::platform::native::win diff --git a/include/cru/win/native/base.hpp b/include/cru/win/native/base.hpp deleted file mode 100644 index a50c6dd1..00000000 --- a/include/cru/win/native/base.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once -#include "../WinPreConfig.hpp" - -#include "cru/common/Base.hpp" - -namespace cru::platform::native::win { -class GodWindow; -class TimerManager; -class WinCursor; -class WinCursorManager; -class WindowClass; -class WindowManager; -class WindowRenderTarget; -class WinNativeWindow; -class WinNativeWindowResolver; -class WinUiApplication; -class WinInputMethodManager; -class WinInputMethodContextRef; -} // namespace cru::platform::native::win diff --git a/include/cru/win/native/cursor.hpp b/include/cru/win/native/cursor.hpp deleted file mode 100644 index 152374d8..00000000 --- a/include/cru/win/native/cursor.hpp +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once -#include "Resource.hpp" - -#include "cru/platform/native/Cursor.hpp" - -#include - -namespace cru::platform::native::win { -class WinCursor : public WinNativeResource, public virtual ICursor { - public: - WinCursor(HCURSOR handle, bool auto_destroy); - - CRU_DELETE_COPY(WinCursor) - CRU_DELETE_MOVE(WinCursor) - - ~WinCursor() override; - - public: - HCURSOR GetHandle() const { return handle_; } - - private: - HCURSOR handle_; - bool auto_destroy_; -}; - -class WinCursorManager : public WinNativeResource, - public virtual ICursorManager { - public: - WinCursorManager(); - - CRU_DELETE_COPY(WinCursorManager) - CRU_DELETE_MOVE(WinCursorManager) - - ~WinCursorManager() override = default; - - public: - std::shared_ptr GetSystemWinCursor(SystemCursorType type); - - std::shared_ptr GetSystemCursor(SystemCursorType type) override { - return std::static_pointer_cast(GetSystemWinCursor(type)); - } - - private: - std::shared_ptr sys_arrow_; - std::shared_ptr sys_hand_; -}; -} // namespace cru::platform::native::win diff --git a/include/cru/win/native/exception.hpp b/include/cru/win/native/exception.hpp deleted file mode 100644 index 6a5265c1..00000000 --- a/include/cru/win/native/exception.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once -#include "../Exception.hpp" - -namespace cru::platform::native::win { -using platform::win::Win32Error; -using platform::win::HResultError; -} // namespace cru::platform::native::win diff --git a/include/cru/win/native/keyboard.hpp b/include/cru/win/native/keyboard.hpp deleted file mode 100644 index 790e0015..00000000 --- a/include/cru/win/native/keyboard.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "Base.hpp" - -#include "cru/platform/native/Keyboard.hpp" - -namespace cru::platform::native::win { -KeyCode VirtualKeyToKeyCode(int virtual_key); -KeyModifier RetrieveKeyMofifier(); -} // namespace cru::platform::native::win diff --git a/include/cru/win/native/resource.hpp b/include/cru/win/native/resource.hpp deleted file mode 100644 index 7afaca0f..00000000 --- a/include/cru/win/native/resource.hpp +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once -#include "Base.hpp" - -#include "cru/platform/Resource.hpp" - -namespace cru::platform::native::win { -class WinNativeResource : public Object, public virtual INativeResource { - public: - static constexpr std::string_view k_platform_id = "Windows"; - - protected: - WinNativeResource() = default; - - public: - CRU_DELETE_COPY(WinNativeResource) - CRU_DELETE_MOVE(WinNativeResource) - - ~WinNativeResource() override = default; - - public: - std::string_view GetPlatformId() const final { return k_platform_id; } -}; -} // namespace cru::platform::native::win diff --git a/include/cru/win/native/window.hpp b/include/cru/win/native/window.hpp deleted file mode 100644 index 80bee39e..00000000 --- a/include/cru/win/native/window.hpp +++ /dev/null @@ -1,174 +0,0 @@ -#pragma once -#include "Resource.hpp" - -#include "cru/platform/native/Window.hpp" -#include "WindowNativeMessageEventArgs.hpp" - -#include - -namespace cru::platform::native::win { -class WinNativeWindow : public WinNativeResource, public virtual INativeWindow { - public: - WinNativeWindow(WinUiApplication* application, WindowClass* window_class, - DWORD window_style, WinNativeWindow* parent); - - CRU_DELETE_COPY(WinNativeWindow) - CRU_DELETE_MOVE(WinNativeWindow) - - ~WinNativeWindow() override; - - public: - std::shared_ptr GetResolver() override { - return std::static_pointer_cast(resolver_); - } - - void Close() override; - - WinNativeWindow* GetParent() override { return parent_window_; } - - bool IsVisible() override; - void SetVisible(bool is_visible) override; - - Size GetClientSize() override; - void SetClientSize(const Size& size) override; - - // Get the rect of the window containing frame. - // The lefttop of the rect is relative to screen lefttop. - Rect GetWindowRect() override; - - // Set the rect of the window containing frame. - // The lefttop of the rect is relative to screen lefttop. - void SetWindowRect(const Rect& rect) override; - - Point GetMousePosition() override; - - bool CaptureMouse() override; - bool ReleaseMouse() override; - - void RequestRepaint() override; - std::unique_ptr BeginPaint() override; - - void SetCursor(std::shared_ptr cursor) override; - - IEvent* DestroyEvent() override { return &destroy_event_; } - IEvent* PaintEvent() override { return &paint_event_; } - IEvent* ResizeEvent() override { return &resize_event_; } - IEvent* FocusEvent() override { return &focus_event_; } - IEvent* MouseEnterLeaveEvent() override { - return &mouse_enter_leave_event_; - } - IEvent* MouseMoveEvent() override { return &mouse_move_event_; } - IEvent* MouseDownEvent() - override { - return &mouse_down_event_; - } - IEvent* MouseUpEvent() - override { - return &mouse_up_event_; - } - IEvent* KeyDownEvent() override { - return &key_down_event_; - } - IEvent* KeyUpEvent() override { - return &key_up_event_; - } - - IEvent* NativeMessageEvent() { - return &native_message_event_; - } - - // Get the handle of the window. Return null if window is invalid. - HWND GetWindowHandle() const { return hwnd_; } - - bool HandleNativeWindowMessage(HWND hwnd, UINT msg, WPARAM w_param, - LPARAM l_param, LRESULT* result); - - WindowRenderTarget* GetWindowRenderTarget() const { - return window_render_target_.get(); - } - - private: - // Get the client rect in pixel. - RECT GetClientRectPixel(); - - //*************** region: native messages *************** - - void OnDestroyInternal(); - void OnPaintInternal(); - void OnResizeInternal(int new_width, int new_height); - - void OnSetFocusInternal(); - void OnKillFocusInternal(); - - void OnMouseMoveInternal(POINT point); - void OnMouseLeaveInternal(); - void OnMouseDownInternal(platform::native::MouseButton button, POINT point); - void OnMouseUpInternal(platform::native::MouseButton button, POINT point); - - void OnMouseWheelInternal(short delta, POINT point); - void OnKeyDownInternal(int virtual_code); - void OnKeyUpInternal(int virtual_code); - - void OnActivatedInternal(); - void OnDeactivatedInternal(); - - private: - WinUiApplication* application_; - - // when delete is called first, it set this to true to indicate - // destroy message handler not to double delete this instance; - // when destroy handler is called first (by user action or method - // Close), it set this to true to indicate delete not call Close - // again. - bool sync_flag_ = false; - - std::shared_ptr resolver_; - - HWND hwnd_; - WinNativeWindow* parent_window_; - - bool has_focus_ = false; - bool is_mouse_in_ = false; - - std::unique_ptr window_render_target_; - - std::shared_ptr cursor_; - - Event destroy_event_; - Event paint_event_; - Event resize_event_; - Event focus_event_; - Event mouse_enter_leave_event_; - Event mouse_move_event_; - Event mouse_down_event_; - Event mouse_up_event_; - Event key_down_event_; - Event key_up_event_; - - Event native_message_event_; -}; - -class WinNativeWindowResolver : public WinNativeResource, - public virtual INativeWindowResolver { - friend WinNativeWindow::~WinNativeWindow(); - - public: - WinNativeWindowResolver(WinNativeWindow* window) : window_(window) {} - - CRU_DELETE_COPY(WinNativeWindowResolver) - CRU_DELETE_MOVE(WinNativeWindowResolver) - - ~WinNativeWindowResolver() override = default; - - public: - INativeWindow* Resolve() override { return window_; } - - private: - void Reset(); - - private: - WinNativeWindow* window_; -}; - -WinNativeWindow* Resolve(gsl::not_null resolver); -} // namespace cru::platform::native::win diff --git a/include/cru/win/string.hpp b/include/cru/win/string.hpp deleted file mode 100644 index 3d68cff7..00000000 --- a/include/cru/win/string.hpp +++ /dev/null @@ -1,107 +0,0 @@ -/* -Because the text encoding problem on Windows, here I write some functions -related to text encoding. The utf-8 and utf-16 conversion function is provided -by win32 api. However win32 api does not provide any function about charactor -iteration or index by code point. (At least I haven't found.) I don't use icu -because it is not easy to build it on Windows and the bundled version in Windows -(https://docs.microsoft.com/en-us/windows/win32/intl/international-components-for-unicode--icu-) -is only available after Windows 10 Creators Update. - -Luckily, both utf-8 and utf-16 encoding are easy to learn and program with if we -only do simple iteration rather than do much sophisticated work about -complicated error situations. (And I learn the internal of the encoding by the -way.) -*/ - -#pragma once -#include "WinPreConfig.hpp" - -#include "cru/common/Base.hpp" - -#include -#include -#include -#include - -namespace cru::platform::win { -std::string ToUtf8String(const std::wstring_view& string); -std::wstring ToUtf16String(const std::string_view& string); - -inline bool IsSurrogatePair(wchar_t c) { return c >= 0xD800 && c <= 0xDFFF; } - -inline bool IsSurrogatePairLeading(wchar_t c) { - return c >= 0xD800 && c <= 0xDBFF; -} - -inline bool IsSurrogatePairTrailing(wchar_t c) { - return c >= 0xDC00 && c <= 0xDFFF; -} - -using CodePoint = std::int32_t; -constexpr CodePoint k_code_point_end = -1; - -class TextEncodeException : public std::runtime_error { - public: - using runtime_error::runtime_error; -}; - -class Utf8Iterator : public Object { - public: - Utf8Iterator(const std::string_view& string) : string_(string) {} - - CRU_DEFAULT_COPY(Utf8Iterator) - CRU_DEFAULT_MOVE(Utf8Iterator) - - ~Utf8Iterator() = default; - - public: - void SetToHead() { position_ = 0; } - - // Advance current position and get next code point. Return k_code_point_end - // if there is no next code unit(point). Throw TextEncodeException if decoding - // fails. - CodePoint Next(); - - int CurrentPosition() const { return this->position_; } - - private: - std::string_view string_; - int position_ = 0; -}; - -class Utf16Iterator : public Object { - static_assert( - sizeof(wchar_t) == 2, - "Emmm, according to my knowledge, wchar_t should be 2-length on " - "Windows. If not, Utf16 will be broken."); - - public: - Utf16Iterator(const std::wstring_view& string) : string_(string) {} - - CRU_DEFAULT_COPY(Utf16Iterator) - CRU_DEFAULT_MOVE(Utf16Iterator) - - ~Utf16Iterator() = default; - - public: - void SetToHead() { position_ = 0; } - - // Advance current position and get next code point. Return k_code_point_end - // if there is no next code unit(point). Throw TextEncodeException if decoding - // fails. - CodePoint Next(); - - int CurrentPosition() const { return this->position_; } - - private: - std::wstring_view string_; - int position_ = 0; -}; - -int IndexUtf8ToUtf16(const std::string_view& utf8_string, int utf8_index, - const std::wstring_view& utf16_string); - -int IndexUtf16ToUtf8(const std::wstring_view& utf16_string, int utf16_index, - const std::string_view& utf8_string); - -} // namespace cru::platform::win -- cgit v1.2.3