aboutsummaryrefslogtreecommitdiff
path: root/src/ui/render
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/render')
-rw-r--r--src/ui/render/border_render_object.cpp52
-rw-r--r--src/ui/render/border_render_object.hpp22
-rw-r--r--src/ui/render/flex_layout_render_object.cpp2
-rw-r--r--src/ui/render/render_object.cpp3
-rw-r--r--src/ui/render/render_object.hpp2
-rw-r--r--src/ui/render/text_render_object.cpp67
-rw-r--r--src/ui/render/text_render_object.hpp39
-rw-r--r--src/ui/render/window_render_object.cpp2
8 files changed, 120 insertions, 69 deletions
diff --git a/src/ui/render/border_render_object.cpp b/src/ui/render/border_render_object.cpp
index 033f59d8..e1550665 100644
--- a/src/ui/render/border_render_object.cpp
+++ b/src/ui/render/border_render_object.cpp
@@ -1,16 +1,45 @@
#include "border_render_object.hpp"
+#include <d2d1_1.h>
+#include <wrl/client.h>
#include <algorithm>
#include "cru_debug.hpp"
#include "exception.hpp"
-#include "graph/graph.hpp"
+#include "graph/graph_manager.hpp"
+#include "graph/graph_util.hpp"
+#include "util/com_util.hpp"
namespace cru::ui::render {
-BorderRenderObject::BorderRenderObject(Microsoft::WRL::ComPtr<ID2D1Brush> brush)
- : border_brush_(std::move(brush)) {}
+BorderRenderObject::BorderRenderObject(ID2D1Brush* brush) {
+ assert(brush);
+ brush->AddRef();
+ this->border_brush_ = brush;
+ try {
+ RecreateGeometry();
+ } catch (...) {
+ brush->Release();
+ throw;
+ }
+}
+
+BorderRenderObject::~BorderRenderObject() {
+ util::SafeRelease(border_brush_);
+ util::SafeRelease(geometry_);
+ util::SafeRelease(border_outer_geometry_);
+}
+
+void BorderRenderObject::SetBrush(ID2D1Brush* new_brush) {
+ assert(new_brush);
+ util::SafeRelease(border_brush_);
+ new_brush->AddRef();
+ border_brush_ = new_brush;
+}
void BorderRenderObject::RecreateGeometry() {
+ util::SafeRelease(geometry_);
+ util::SafeRelease(border_outer_geometry_);
+
const auto d2d_factory = graph::GraphManager::GetInstance()->GetD2D1Factory();
Microsoft::WRL::ComPtr<ID2D1PathGeometry> geometry;
@@ -19,8 +48,8 @@ void BorderRenderObject::RecreateGeometry() {
Microsoft::WRL::ComPtr<ID2D1PathGeometry> border_outer_geometry;
ThrowIfFailed(d2d_factory->CreatePathGeometry(&border_outer_geometry));
- ID2D1GeometrySink* sink;
- auto f = [sink](const Rect& rect, const CornerRadius& corner) {
+ Microsoft::WRL::ComPtr<ID2D1GeometrySink> sink;
+ auto f = [&sink](const Rect& rect, const CornerRadius& corner) {
sink->BeginFigure(D2D1::Point2F(rect.left + corner.left_top.x, rect.top),
D2D1_FIGURE_BEGIN_FILLED);
sink->AddLine(
@@ -53,21 +82,21 @@ void BorderRenderObject::RecreateGeometry() {
ThrowIfFailed(border_outer_geometry->Open(&sink));
f(outer_rect, corner_radius_);
ThrowIfFailed(sink->Close());
- sink->Release();
+ sink = nullptr;
const Rect inner_rect = outer_rect.Shrink(border_thickness_);
ThrowIfFailed(geometry->Open(&sink));
f(outer_rect, corner_radius_);
f(inner_rect, corner_radius_);
ThrowIfFailed(sink->Close());
- sink->Release();
+ sink = nullptr;
- geometry_ = std::move(geometry);
- border_outer_geometry_ = std::move(border_outer_geometry);
+ geometry_ = geometry.Detach();
+ border_outer_geometry_ = border_outer_geometry.Detach();
}
void BorderRenderObject::Draw(ID2D1RenderTarget* render_target) {
- render_target->FillGeometry(geometry_.Get(), border_brush_.Get());
+ render_target->FillGeometry(geometry_, border_brush_);
if (const auto child = GetChild()) {
auto offset = child->GetOffset();
graph::WithTransform(render_target,
@@ -167,7 +196,8 @@ void BorderRenderObject::OnLayoutCore(const Rect& rect) {
}
if (coerced_content_available_size.height < 0) {
debug::DebugMessage(
- L"Layout: vertical length of padding, border and margin is bigger than "
+ L"Layout: vertical length of padding, border and margin is bigger "
+ L"than "
L"available length.");
coerced_content_available_size.height = 0;
}
diff --git a/src/ui/render/border_render_object.hpp b/src/ui/render/border_render_object.hpp
index d6effc21..eccb1219 100644
--- a/src/ui/render/border_render_object.hpp
+++ b/src/ui/render/border_render_object.hpp
@@ -28,20 +28,18 @@ struct CornerRadius {
class BorderRenderObject : public RenderObject {
public:
- explicit BorderRenderObject(Microsoft::WRL::ComPtr<ID2D1Brush> brush);
+ explicit BorderRenderObject(ID2D1Brush* brush);
BorderRenderObject(const BorderRenderObject& other) = delete;
BorderRenderObject(BorderRenderObject&& other) = delete;
BorderRenderObject& operator=(const BorderRenderObject& other) = delete;
BorderRenderObject& operator=(BorderRenderObject&& other) = delete;
- ~BorderRenderObject() override = default;
+ ~BorderRenderObject() override;
bool IsEnabled() const { return is_enabled_; }
void SetEnabled(bool enabled) { is_enabled_ = enabled; }
- Microsoft::WRL::ComPtr<ID2D1Brush> GetBrush() const { return border_brush_; }
- void SetBrush(const Microsoft::WRL::ComPtr<ID2D1Brush> new_brush) {
- border_brush_ = std::move(new_brush);
- }
+ ID2D1Brush* GetBrush() const { return border_brush_; }
+ void SetBrush(ID2D1Brush* new_brush);
Thickness GetBorderWidth() const { return border_thickness_; }
void SetBorderWidth(const Thickness& thickness) { border_thickness_ = thickness; }
@@ -51,11 +49,11 @@ class BorderRenderObject : public RenderObject {
corner_radius_ = new_corner_radius;
}
- void RecreateGeometry(); // TODO
+ void RecreateGeometry();
- void Draw(ID2D1RenderTarget* render_target) override; // TODO
+ void Draw(ID2D1RenderTarget* render_target) override;
- RenderObject* HitTest(const Point& point) override; // TODO
+ RenderObject* HitTest(const Point& point) override;
protected:
void OnAddChild(RenderObject* new_child, int position) override;
@@ -73,11 +71,11 @@ class BorderRenderObject : public RenderObject {
private:
bool is_enabled_ = false;
- Microsoft::WRL::ComPtr<ID2D1Brush> border_brush_;
+ ID2D1Brush* border_brush_ = nullptr;
Thickness border_thickness_ = Thickness::Zero();
CornerRadius corner_radius_{};
- Microsoft::WRL::ComPtr<ID2D1Geometry> geometry_{nullptr};
- Microsoft::WRL::ComPtr<ID2D1Geometry> border_outer_geometry_{nullptr};
+ ID2D1Geometry* geometry_ = nullptr;
+ ID2D1Geometry* border_outer_geometry_ = nullptr;
};
} // namespace cru::ui::render
diff --git a/src/ui/render/flex_layout_render_object.cpp b/src/ui/render/flex_layout_render_object.cpp
index 4708d187..e4d327f1 100644
--- a/src/ui/render/flex_layout_render_object.cpp
+++ b/src/ui/render/flex_layout_render_object.cpp
@@ -4,7 +4,7 @@
#include <functional>
#include "cru_debug.hpp"
-#include "graph/graph.hpp"
+#include "graph/graph_util.hpp"
namespace cru::ui::render {
FlexChildLayoutData* FlexLayoutRenderObject::GetChildLayoutData(int position) {
diff --git a/src/ui/render/render_object.cpp b/src/ui/render/render_object.cpp
index f56baa8f..232eda41 100644
--- a/src/ui/render/render_object.cpp
+++ b/src/ui/render/render_object.cpp
@@ -1,8 +1,5 @@
#include "render_object.hpp"
-#include <d2d1.h>
-#include <dwrite.h>
-
#include "cru_debug.hpp"
namespace cru::ui::render {
diff --git a/src/ui/render/render_object.hpp b/src/ui/render/render_object.hpp
index 51b0c3ae..abdda605 100644
--- a/src/ui/render/render_object.hpp
+++ b/src/ui/render/render_object.hpp
@@ -1,7 +1,6 @@
#pragma once
#include "pre.hpp"
-#include <optional>
#include <vector>
#include "base.hpp"
@@ -9,7 +8,6 @@
// forward declarations
struct ID2D1RenderTarget;
-
namespace cru::ui {
class Control;
}
diff --git a/src/ui/render/text_render_object.cpp b/src/ui/render/text_render_object.cpp
index e8967d48..b66fffa3 100644
--- a/src/ui/render/text_render_object.cpp
+++ b/src/ui/render/text_render_object.cpp
@@ -5,19 +5,61 @@
#include <algorithm>
#include "exception.hpp"
-#include "graph/graph.hpp"
+#include "graph/graph_manager.hpp"
+#include "graph/graph_util.hpp"
+#include "util/com_util.hpp"
namespace cru::ui::render {
-TextRenderObject::TextRenderObject(
- Microsoft::WRL::ComPtr<ID2D1Brush> brush,
- Microsoft::WRL::ComPtr<IDWriteTextFormat> format,
- Microsoft::WRL::ComPtr<ID2D1Brush> selection_brush)
- : brush_(std::move(brush)),
- text_format_(std::move(format)),
- selection_brush_(std::move(selection_brush)) {
+TextRenderObject::TextRenderObject(ID2D1Brush* brush, IDWriteTextFormat* format,
+ ID2D1Brush* selection_brush) {
+ assert(brush);
+ assert(format);
+ assert(selection_brush);
+ brush->AddRef();
+ format->AddRef();
+ selection_brush->AddRef();
+ this->brush_ = brush;
+ this->text_format_ = format;
+ this->selection_brush_ = selection_brush;
+ try {
+ RecreateTextLayout();
+ } catch (...) {
+ brush->Release();
+ format->Release();
+ selection_brush->Release();
+ throw;
+ }
+}
+
+TextRenderObject::~TextRenderObject() {
+ util::SafeRelease(brush_);
+ util::SafeRelease(text_format_);
+ util::SafeRelease(text_layout_);
+ util::SafeRelease(selection_brush_);
+}
+
+void TextRenderObject::SetBrush(ID2D1Brush* new_brush) {
+ assert(new_brush);
+ util::SafeRelease(brush_);
+ new_brush->AddRef();
+ brush_ = new_brush;
+}
+
+void TextRenderObject::SetTextFormat(IDWriteTextFormat* new_text_format) {
+ assert(new_text_format);
+ util::SafeRelease(text_format_);
+ new_text_format->AddRef();
+ text_format_ = new_text_format;
RecreateTextLayout();
}
+void TextRenderObject::SetSelectionBrush(ID2D1Brush* new_brush) {
+ assert(new_brush);
+ util::SafeRelease(selection_brush_);
+ new_brush->AddRef();
+ selection_brush_ = new_brush;
+}
+
namespace {
void DrawSelectionRect(ID2D1RenderTarget* render_target,
IDWriteTextLayout* layout, ID2D1Brush* brush,
@@ -54,9 +96,8 @@ void TextRenderObject::Draw(ID2D1RenderTarget* render_target) {
D2D1::Matrix3x2F::Translation(GetMargin().left + GetPadding().left,
GetMargin().top + GetPadding().top),
[this](auto rt) {
- DrawSelectionRect(rt, text_layout_.Get(), selection_brush_.Get(),
- selection_range_);
- rt->DrawTextLayout(D2D1::Point2F(), text_layout_.Get(), brush_.Get());
+ DrawSelectionRect(rt, text_layout_, selection_brush_, selection_range_);
+ rt->DrawTextLayout(D2D1::Point2F(), text_layout_, brush_);
});
}
@@ -99,7 +140,7 @@ void TextRenderObject::OnLayoutContent(const Rect& content_rect) {}
void TextRenderObject::RecreateTextLayout() {
assert(text_format_ != nullptr);
- text_layout_ = nullptr; // release last one
+ util::SafeRelease(text_layout_);
const auto dwrite_factory =
graph::GraphManager::GetInstance()->GetDWriteFactory();
@@ -107,7 +148,7 @@ void TextRenderObject::RecreateTextLayout() {
const auto&& size = GetSize();
ThrowIfFailed(dwrite_factory->CreateTextLayout(
- text_.c_str(), static_cast<UINT32>(text_.size()), text_format_.Get(),
+ text_.c_str(), static_cast<UINT32>(text_.size()), text_format_,
size.width, size.height, &text_layout_));
}
} // namespace cru::ui::render
diff --git a/src/ui/render/text_render_object.hpp b/src/ui/render/text_render_object.hpp
index ac874b75..30d78736 100644
--- a/src/ui/render/text_render_object.hpp
+++ b/src/ui/render/text_render_object.hpp
@@ -1,8 +1,6 @@
#pragma once
#include "pre.hpp"
-#include <wrl/client.h> // for ComPtr
-
#include "render_object.hpp"
// forward declarations
@@ -13,14 +11,13 @@ struct IDWriteTextLayout;
namespace cru::ui::render {
class TextRenderObject : public RenderObject {
public:
- TextRenderObject(Microsoft::WRL::ComPtr<ID2D1Brush> brush,
- Microsoft::WRL::ComPtr<IDWriteTextFormat> format,
- Microsoft::WRL::ComPtr<ID2D1Brush> selection_brush);
+ TextRenderObject(ID2D1Brush* brush, IDWriteTextFormat* format,
+ ID2D1Brush* selection_brush);
TextRenderObject(const TextRenderObject& other) = delete;
TextRenderObject(TextRenderObject&& other) = delete;
TextRenderObject& operator=(const TextRenderObject& other) = delete;
TextRenderObject& operator=(TextRenderObject&& other) = delete;
- ~TextRenderObject() override = default;
+ ~TextRenderObject() override;
String GetText() const { return text_; }
void SetText(String new_text) {
@@ -28,19 +25,11 @@ class TextRenderObject : public RenderObject {
RecreateTextLayout();
}
- Microsoft::WRL::ComPtr<ID2D1Brush> GetBrush() const { return brush_; }
- void SetBrush(Microsoft::WRL::ComPtr<ID2D1Brush> new_brush) {
- brush_ = std::move(new_brush);
- }
+ ID2D1Brush* GetBrush() const { return brush_; }
+ void SetBrush(ID2D1Brush* new_brush);
- Microsoft::WRL::ComPtr<IDWriteTextFormat> GetTextFormat() const {
- return text_format_;
- }
- void SetTextFormat(
- Microsoft::WRL::ComPtr<IDWriteTextFormat> new_text_format) {
- text_format_ = std::move(new_text_format);
- RecreateTextLayout();
- }
+ IDWriteTextFormat* GetTextFormat() const { return text_format_; }
+ void SetTextFormat(IDWriteTextFormat* new_text_format);
std::optional<TextRange> GetSelectionRange() const {
return selection_range_;
@@ -49,12 +38,10 @@ class TextRenderObject : public RenderObject {
selection_range_ = std::move(new_range);
}
- Microsoft::WRL::ComPtr<ID2D1Brush> GetSelectionBrush() const {
+ ID2D1Brush* GetSelectionBrush() const {
return selection_brush_;
}
- void SetSelectionBrush(Microsoft::WRL::ComPtr<ID2D1Brush> new_brush) {
- selection_brush_ = std::move(new_brush);
- }
+ void SetSelectionBrush(ID2D1Brush* new_brush);
void Draw(ID2D1RenderTarget* render_target) override;
@@ -72,11 +59,11 @@ class TextRenderObject : public RenderObject {
private:
String text_;
- Microsoft::WRL::ComPtr<ID2D1Brush> brush_;
- Microsoft::WRL::ComPtr<IDWriteTextFormat> text_format_;
- Microsoft::WRL::ComPtr<IDWriteTextLayout> text_layout_;
+ ID2D1Brush* brush_;
+ IDWriteTextFormat* text_format_;
+ IDWriteTextLayout* text_layout_;
std::optional<TextRange> selection_range_ = std::nullopt;
- Microsoft::WRL::ComPtr<ID2D1Brush> selection_brush_;
+ ID2D1Brush* selection_brush_;
};
} // namespace cru::ui::render
diff --git a/src/ui/render/window_render_object.cpp b/src/ui/render/window_render_object.cpp
index f198c2fa..44c3c426 100644
--- a/src/ui/render/window_render_object.cpp
+++ b/src/ui/render/window_render_object.cpp
@@ -1,6 +1,6 @@
#include "window_render_object.hpp"
-#include "graph/graph.hpp"
+#include "graph/graph_util.hpp"
#include "ui/window.hpp"
namespace cru::ui::render {