aboutsummaryrefslogtreecommitdiff
path: root/src/win/graph
diff options
context:
space:
mode:
Diffstat (limited to 'src/win/graph')
-rw-r--r--src/win/graph/direct/CMakeLists.txt8
-rw-r--r--src/win/graph/direct/brush.cpp7
-rw-r--r--src/win/graph/direct/factory.cpp (renamed from src/win/graph/direct/graph_factory.cpp)56
-rw-r--r--src/win/graph/direct/font.cpp20
-rw-r--r--src/win/graph/direct/geometry.cpp22
-rw-r--r--src/win/graph/direct/painter.cpp80
-rw-r--r--src/win/graph/direct/resource.cpp14
-rw-r--r--src/win/graph/direct/text_layout.cpp47
8 files changed, 116 insertions, 138 deletions
diff --git a/src/win/graph/direct/CMakeLists.txt b/src/win/graph/direct/CMakeLists.txt
index fa5e3a99..b277fa32 100644
--- a/src/win/graph/direct/CMakeLists.txt
+++ b/src/win/graph/direct/CMakeLists.txt
@@ -4,21 +4,21 @@ add_library(cru_win_graph_direct STATIC
brush.cpp
font.cpp
geometry.cpp
- graph_factory.cpp
+ factory.cpp
painter.cpp
+ resource.cpp
text_layout.cpp
)
target_sources(cru_win_graph_direct PUBLIC
${CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR}/brush.hpp
${CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR}/com_resource.hpp
${CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR}/convert_util.hpp
- ${CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR}/direct_factory.hpp
${CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR}/exception.hpp
${CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR}/font.hpp
${CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR}/geometry.hpp
- ${CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR}/graph_factory.hpp
+ ${CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR}/factory.hpp
${CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR}/painter.hpp
- ${CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR}/platform_id.hpp
+ ${CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR}/resource.hpp
${CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR}/text_layout.hpp
)
target_link_libraries(cru_win_graph_direct PUBLIC D3D11 D2d1 DWrite cru_win_base cru_platform_graph)
diff --git a/src/win/graph/direct/brush.cpp b/src/win/graph/direct/brush.cpp
index 1f17cd03..17024a66 100644
--- a/src/win/graph/direct/brush.cpp
+++ b/src/win/graph/direct/brush.cpp
@@ -2,17 +2,18 @@
#include "cru/win/graph/direct/convert_util.hpp"
#include "cru/win/graph/direct/exception.hpp"
+#include "cru/win/graph/direct/factory.hpp"
#include <cassert>
namespace cru::platform::graph::win::direct {
-D2DSolidColorBrush::D2DSolidColorBrush(IDirectFactory* factory) {
- assert(factory);
+D2DSolidColorBrush::D2DSolidColorBrush(DirectGraphFactory* factory)
+ : DirectGraphResource(factory) {
ThrowIfFailed(factory->GetD2D1DeviceContext()->CreateSolidColorBrush(
Convert(color_), &brush_));
}
-void D2DSolidColorBrush::OnSetColor(const Color& color) {
+void D2DSolidColorBrush::SetColor(const Color& color) {
brush_->SetColor(Convert(color));
}
} // namespace cru::platform::graph::win::direct
diff --git a/src/win/graph/direct/graph_factory.cpp b/src/win/graph/direct/factory.cpp
index 49752d0b..7882c3ee 100644
--- a/src/win/graph/direct/graph_factory.cpp
+++ b/src/win/graph/direct/factory.cpp
@@ -1,4 +1,4 @@
-#include "cru/win/graph/direct/graph_factory.hpp"
+#include "cru/win/graph/direct/factory.hpp"
#include "cru/win/graph/direct/brush.hpp"
#include "cru/win/graph/direct/exception.hpp"
@@ -11,37 +11,6 @@
#include <utility>
namespace cru::platform::graph::win::direct {
-namespace {
-DirectGraphFactory* instance = nullptr;
-}
-} // namespace cru::platform::graph::win::direct
-
-namespace cru::platform::graph {
-void GraphFactoryAutoDeleteExitHandler() {
- const auto i =
- ::cru::platform::graph::win::direct::instance; // avoid long namespace
- // prefix
- if (i == nullptr) return;
- if (i->IsAutoDelete()) delete i;
-}
-
-GraphFactory* GraphFactory::CreateInstance() {
- auto& i = ::cru::platform::graph::win::direct::instance; // avoid long
- // namespace prefix
- assert(i == nullptr);
- i = new ::cru::platform::graph::win::direct::DirectGraphFactory();
- std::atexit(&GraphFactoryAutoDeleteExitHandler);
- return i;
-}
-
-GraphFactory* GraphFactory::GetInstance() {
- return ::cru::platform::graph::win::direct::instance;
-}
-} // namespace cru::platform::graph
-
-namespace cru::platform::graph::win::direct {
-DirectGraphFactory* DirectGraphFactory::GetInstance() { return instance; }
-
DirectGraphFactory::DirectGraphFactory() {
UINT creation_flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
@@ -89,23 +58,22 @@ DirectGraphFactory::DirectGraphFactory() {
&dwrite_system_font_collection_));
}
-DirectGraphFactory::~DirectGraphFactory() { instance = nullptr; }
-
-D2DSolidColorBrush* DirectGraphFactory::CreateSolidColorBrush() {
- return new D2DSolidColorBrush(this);
+std::unique_ptr<ISolidColorBrush> DirectGraphFactory::CreateSolidColorBrush() {
+ return std::make_unique<D2DSolidColorBrush>(this);
}
-D2DGeometryBuilder* DirectGraphFactory::CreateGeometryBuilder() {
- return new D2DGeometryBuilder(this);
+std::unique_ptr<IGeometryBuilder> DirectGraphFactory::CreateGeometryBuilder() {
+ return std::make_unique<D2DGeometryBuilder>(this);
}
-DWriteFont* DirectGraphFactory::CreateFont(
- const std::wstring_view& font_family, float font_size) {
- return new DWriteFont(this, font_family, font_size);
+std::unique_ptr<IFont> DirectGraphFactory::CreateFont(
+ const std::string_view& font_family, float font_size) {
+ return std::make_unique<DWriteFont>(this, font_family, font_size);
}
-DWriteTextLayout* DirectGraphFactory::CreateTextLayout(
- std::shared_ptr<Font> font, std::wstring text) {
- return new DWriteTextLayout(this, std::move(font), std::move(text));
+std::unique_ptr<ITextLayout> DirectGraphFactory::CreateTextLayout(
+ std::shared_ptr<IFont> font, std::string text) {
+ return std::make_unique<DWriteTextLayout>(this, std::move(font),
+ std::move(text));
}
} // namespace cru::platform::graph::win::direct
diff --git a/src/win/graph/direct/font.cpp b/src/win/graph/direct/font.cpp
index 5d7b4483..8e881f84 100644
--- a/src/win/graph/direct/font.cpp
+++ b/src/win/graph/direct/font.cpp
@@ -1,25 +1,29 @@
#include "cru/win/graph/direct/font.hpp"
-#include "cru/win/exception.hpp"
#include "cru/win/graph/direct/exception.hpp"
+#include "cru/win/graph/direct/factory.hpp"
+#include "cru/win/string.hpp"
#include <array>
#include <cassert>
#include <utility>
namespace cru::platform::graph::win::direct {
-DWriteFont::DWriteFont(IDirectFactory* factory,
- const std::wstring_view& font_family, float font_size) {
- assert(factory);
+DWriteFont::DWriteFont(DirectGraphFactory* factory,
+ const std::string_view& font_family, float font_size)
+ : DirectGraphResource(factory) {
+ // Get locale
std::array<wchar_t, LOCALE_NAME_MAX_LENGTH> buffer;
if (!::GetUserDefaultLocaleName(buffer.data(),
static_cast<int>(buffer.size())))
- throw platform::win::Win32Error(::GetLastError(), "Failed to get locale.");
+ throw platform::win::Win32Error(
+ ::GetLastError(), "Failed to get locale when create dwrite font.");
+
+ const std::wstring&& wff = cru::platform::win::ToUtf16String(font_family);
ThrowIfFailed(factory->GetDWriteFactory()->CreateTextFormat(
- font_family.data(), nullptr, DWRITE_FONT_WEIGHT_NORMAL,
- DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, font_size,
- buffer.data(), &text_format_));
+ wff.data(), nullptr, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL,
+ DWRITE_FONT_STRETCH_NORMAL, font_size, buffer.data(), &text_format_));
ThrowIfFailed(text_format_->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER));
ThrowIfFailed(
diff --git a/src/win/graph/direct/geometry.cpp b/src/win/graph/direct/geometry.cpp
index 470addee..5540edab 100644
--- a/src/win/graph/direct/geometry.cpp
+++ b/src/win/graph/direct/geometry.cpp
@@ -2,16 +2,22 @@
#include "cru/win/graph/direct/convert_util.hpp"
#include "cru/win/graph/direct/exception.hpp"
+#include "cru/win/graph/direct/factory.hpp"
#include <cassert>
namespace cru::platform::graph::win::direct {
-D2DGeometryBuilder::D2DGeometryBuilder(IDirectFactory* factory) {
- assert(factory);
+D2DGeometryBuilder::D2DGeometryBuilder(DirectGraphFactory* factory)
+ : DirectGraphResource(factory) {
ThrowIfFailed(factory->GetD2D1Factory()->CreatePathGeometry(&geometry_));
ThrowIfFailed(geometry_->Open(&geometry_sink_));
}
+void D2DGeometryBuilder::CheckValidation() {
+ if (!IsValid())
+ throw ReuseException("The geometry builder is already disposed.");
+}
+
void D2DGeometryBuilder::BeginFigure(const Point& point) {
CheckValidation();
geometry_sink_->BeginFigure(Convert(point), D2D1_FIGURE_BEGIN_FILLED);
@@ -35,19 +41,19 @@ void D2DGeometryBuilder::CloseFigure(bool close) {
: D2D1_FIGURE_END_OPEN);
}
-Geometry* D2DGeometryBuilder::Build() {
+std::unique_ptr<IGeometry> D2DGeometryBuilder::Build() {
CheckValidation();
ThrowIfFailed(geometry_sink_->Close());
geometry_sink_ = nullptr;
- const auto geometry = new D2DGeometry(std::move(geometry_));
+ auto geometry =
+ std::make_unique<D2DGeometry>(GetDirectFactory(), std::move(geometry_));
geometry_ = nullptr;
return geometry;
}
-D2DGeometry::D2DGeometry(Microsoft::WRL::ComPtr<ID2D1PathGeometry> geometry) {
- assert(geometry);
- geometry_ = std::move(geometry);
-}
+D2DGeometry::D2DGeometry(DirectGraphFactory* factory,
+ Microsoft::WRL::ComPtr<ID2D1PathGeometry> geometry)
+ : DirectGraphResource(factory), geometry_(std::move(geometry)) {}
bool D2DGeometry::FillContains(const Point& point) {
BOOL result;
diff --git a/src/win/graph/direct/painter.cpp b/src/win/graph/direct/painter.cpp
index 6fbbf957..fb2a6e7f 100644
--- a/src/win/graph/direct/painter.cpp
+++ b/src/win/graph/direct/painter.cpp
@@ -1,5 +1,6 @@
#include "cru/win/graph/direct/painter.hpp"
+#include "cru/platform/check.hpp"
#include "cru/win/graph/direct/brush.hpp"
#include "cru/win/graph/direct/convert_util.hpp"
#include "cru/win/graph/direct/exception.hpp"
@@ -10,89 +11,63 @@
#include <type_traits>
namespace cru::platform::graph::win::direct {
-
-namespace {
-template <typename T, typename U, typename = void>
-struct is_static_castable : std::false_type {};
-
-template <typename T, typename U>
-struct is_static_castable<
- T, U, std::void_t<decltype(static_cast<U>(std::declval<T>()))>>
- : std::true_type {};
-
-template <typename TDes, typename TSrc>
-TDes* CheckAndCast(TSrc* src) {
- assert(src);
- assert(IsDirectResource(src));
- if constexpr (is_static_castable<TSrc*, TDes*>::value)
- return static_cast<TDes*>(src);
- else {
- TDes* d = dynamic_cast<TDes*>(src);
- assert(d);
- return d;
- }
-}
-} // namespace
-
D2DPainter::D2DPainter(ID2D1RenderTarget* render_target) {
assert(render_target);
render_target_ = render_target;
}
platform::Matrix D2DPainter::GetTransform() {
- assert(IsValid());
+ CheckValidation();
D2D1_MATRIX_3X2_F m;
render_target_->GetTransform(&m);
return Convert(m);
}
void D2DPainter::SetTransform(const platform::Matrix& matrix) {
- assert(IsValid());
+ CheckValidation();
render_target_->SetTransform(Convert(matrix));
}
void D2DPainter::Clear(const Color& color) {
- assert(IsValid());
+ CheckValidation();
render_target_->Clear(Convert(color));
}
-void D2DPainter::StrokeRectangle(const Rect& rectangle, Brush* brush,
+void D2DPainter::StrokeRectangle(const Rect& rectangle, IBrush* brush,
float width) {
- assert(IsValid());
- const auto b = CheckAndCast<ID2DBrush>(brush);
+ CheckValidation();
+ const auto b = CheckPlatform<ID2DBrush>(brush, GetPlatformId());
render_target_->DrawRectangle(Convert(rectangle), b->GetD2DBrushInterface(),
width);
}
-void D2DPainter::FillRectangle(const Rect& rectangle, Brush* brush) {
- assert(IsValid());
- const auto b = CheckAndCast<ID2DBrush>(brush);
+void D2DPainter::FillRectangle(const Rect& rectangle, IBrush* brush) {
+ CheckValidation();
+ const auto b = CheckPlatform<ID2DBrush>(brush, GetPlatformId());
render_target_->FillRectangle(Convert(rectangle), b->GetD2DBrushInterface());
}
-void D2DPainter::StrokeGeometry(Geometry* geometry, Brush* brush, float width) {
- assert(IsValid());
- const auto g = CheckAndCast<D2DGeometry>(geometry);
- const auto b = CheckAndCast<ID2DBrush>(brush);
-
+void D2DPainter::StrokeGeometry(IGeometry* geometry, IBrush* brush,
+ float width) {
+ CheckValidation();
+ const auto g = CheckPlatform<D2DGeometry>(geometry, GetPlatformId());
+ const auto b = CheckPlatform<ID2DBrush>(brush, GetPlatformId());
render_target_->DrawGeometry(g->GetComInterface(), b->GetD2DBrushInterface(),
width);
}
-void D2DPainter::FillGeometry(Geometry* geometry, Brush* brush) {
- assert(IsValid());
- const auto g = CheckAndCast<D2DGeometry>(geometry);
- const auto b = CheckAndCast<ID2DBrush>(brush);
-
+void D2DPainter::FillGeometry(IGeometry* geometry, IBrush* brush) {
+ CheckValidation();
+ const auto g = CheckPlatform<D2DGeometry>(geometry, GetPlatformId());
+ const auto b = CheckPlatform<ID2DBrush>(brush, GetPlatformId());
render_target_->FillGeometry(g->GetComInterface(), b->GetD2DBrushInterface());
}
-void D2DPainter::DrawText(const Point& offset, TextLayout* text_layout,
- Brush* brush) {
- assert(IsValid());
- const auto t = CheckAndCast<DWriteTextLayout>(text_layout);
- const auto b = CheckAndCast<ID2DBrush>(brush);
-
+void D2DPainter::DrawText(const Point& offset, ITextLayout* text_layout,
+ IBrush* brush) {
+ CheckValidation();
+ const auto t = CheckPlatform<DWriteTextLayout>(text_layout, GetPlatformId());
+ const auto b = CheckPlatform<ID2DBrush>(brush, GetPlatformId());
render_target_->DrawTextLayout(Convert(offset), t->GetComInterface(),
b->GetD2DBrushInterface());
}
@@ -103,4 +78,11 @@ void D2DPainter::EndDraw() {
DoEndDraw();
}
}
+
+void D2DPainter::CheckValidation() {
+ if (!is_drawing_) {
+ throw cru::platform::ReuseException(
+ "Can't do that on painter after end drawing.");
+ }
+}
} // namespace cru::platform::graph::win::direct
diff --git a/src/win/graph/direct/resource.cpp b/src/win/graph/direct/resource.cpp
new file mode 100644
index 00000000..2acc91e4
--- /dev/null
+++ b/src/win/graph/direct/resource.cpp
@@ -0,0 +1,14 @@
+#include "cru/win/graph/direct/resource.hpp"
+
+#include "cru/win/graph/direct/factory.hpp"
+
+#include <cassert>
+
+namespace cru::platform::graph::win::direct {
+DirectGraphResource::DirectGraphResource(DirectGraphFactory* factory)
+ : factory_(factory) {
+ assert(factory);
+}
+
+IGraphFactory* DirectGraphResource::GetGraphFactory() { return factory_; }
+} // namespace cru::platform::graph::win::direct
diff --git a/src/win/graph/direct/text_layout.cpp b/src/win/graph/direct/text_layout.cpp
index 23a14b2a..a1750799 100644
--- a/src/win/graph/direct/text_layout.cpp
+++ b/src/win/graph/direct/text_layout.cpp
@@ -1,46 +1,49 @@
#include "cru/win/graph/direct/text_layout.hpp"
+#include "cru/platform/check.hpp"
#include "cru/win/graph/direct/exception.hpp"
+#include "cru/win/graph/direct/factory.hpp"
+#include "cru/win/graph/direct/font.hpp"
+#include "cru/win/string.hpp"
#include <cassert>
#include <utility>
namespace cru::platform::graph::win::direct {
-DWriteTextLayout::DWriteTextLayout(IDirectFactory* factory,
- std::shared_ptr<Font> font,
- std::wstring text)
- : text_(std::move(text)) {
- assert(factory);
+DWriteTextLayout::DWriteTextLayout(DirectGraphFactory* factory,
+ std::shared_ptr<IFont> font,
+ std::string text)
+ : DirectGraphResource(factory), text_(std::move(text)) {
assert(font);
- assert(IsDirectResource(font.get()));
- factory_ = factory;
- font_ = std::static_pointer_cast<DWriteFont>(font);
+ font_ = CheckPlatform<DWriteFont>(font, GetPlatformId());
+
+ w_text_ = cru::platform::win::ToUtf16String(text_);
ThrowIfFailed(factory->GetDWriteFactory()->CreateTextLayout(
- text_.c_str(), static_cast<UINT32>(text_.size()),
+ w_text_.c_str(), static_cast<UINT32>(w_text_.size()),
font_->GetComInterface(), max_width_, max_height_, &text_layout_));
}
-std::wstring DWriteTextLayout::GetText() { return text_; }
+DWriteTextLayout::~DWriteTextLayout() = default;
+
+std::string DWriteTextLayout::GetText() { return text_; }
-void DWriteTextLayout::SetText(std::wstring new_text) {
+void DWriteTextLayout::SetText(std::string new_text) {
text_.swap(new_text);
- ThrowIfFailed(factory_->GetDWriteFactory()->CreateTextLayout(
- text_.c_str(), static_cast<UINT32>(text_.size()),
+ w_text_ = cru::platform::win::ToUtf16String(text_);
+ ThrowIfFailed(GetDirectFactory()->GetDWriteFactory()->CreateTextLayout(
+ w_text_.c_str(), static_cast<UINT32>(w_text_.size()),
font_->GetComInterface(), max_width_, max_height_, &text_layout_));
}
-std::shared_ptr<Font> DWriteTextLayout::GetFont() {
- return std::static_pointer_cast<Font>(font_);
+std::shared_ptr<IFont> DWriteTextLayout::GetFont() {
+ return std::dynamic_pointer_cast<IFont>(font_);
}
-void DWriteTextLayout::SetFont(std::shared_ptr<Font> font) {
- assert(IsDirectResource(font.get()));
- auto f = std::static_pointer_cast<DWriteFont>(font);
-
- f.swap(font_);
- ThrowIfFailed(factory_->GetDWriteFactory()->CreateTextLayout(
- text_.c_str(), static_cast<UINT32>(text_.size()),
+void DWriteTextLayout::SetFont(std::shared_ptr<IFont> font) {
+ font_ = CheckPlatform<DWriteFont>(font, GetPlatformId());
+ ThrowIfFailed(GetDirectFactory()->GetDWriteFactory()->CreateTextLayout(
+ w_text_.c_str(), static_cast<UINT32>(w_text_.size()),
font_->GetComInterface(), max_width_, max_height_, &text_layout_));
}