aboutsummaryrefslogtreecommitdiff
path: root/src/win/graphics
diff options
context:
space:
mode:
Diffstat (limited to 'src/win/graphics')
-rw-r--r--src/win/graphics/direct/Brush.cpp4
-rw-r--r--src/win/graphics/direct/Factory.cpp20
-rw-r--r--src/win/graphics/direct/Font.cpp4
-rw-r--r--src/win/graphics/direct/Geometry.cpp10
-rw-r--r--src/win/graphics/direct/Painter.cpp42
-rw-r--r--src/win/graphics/direct/Resource.cpp6
-rw-r--r--src/win/graphics/direct/TextLayout.cpp59
-rw-r--r--src/win/graphics/direct/WindowRenderTarget.cpp2
8 files changed, 113 insertions, 34 deletions
diff --git a/src/win/graphics/direct/Brush.cpp b/src/win/graphics/direct/Brush.cpp
index b7842b97..eb6ea973 100644
--- a/src/win/graphics/direct/Brush.cpp
+++ b/src/win/graphics/direct/Brush.cpp
@@ -5,8 +5,8 @@
#include "cru/win/graphics/direct/Factory.hpp"
namespace cru::platform::graphics::win::direct {
-D2DSolidColorBrush::D2DSolidColorBrush(DirectGraphFactory* factory)
- : DirectGraphResource(factory) {
+D2DSolidColorBrush::D2DSolidColorBrush(DirectGraphicsFactory* factory)
+ : DirectGraphicsResource(factory) {
ThrowIfFailed(factory->GetDefaultD2D1DeviceContext()->CreateSolidColorBrush(
Convert(color_), &brush_));
}
diff --git a/src/win/graphics/direct/Factory.cpp b/src/win/graphics/direct/Factory.cpp
index 6694801f..4c4f1a9a 100644
--- a/src/win/graphics/direct/Factory.cpp
+++ b/src/win/graphics/direct/Factory.cpp
@@ -27,7 +27,7 @@ void InitializeCom() {
void UninitializeCom() { ::CoUninitialize(); }
} // namespace
-DirectGraphFactory::DirectGraphFactory() {
+DirectGraphicsFactory::DirectGraphicsFactory() {
// TODO! Detect repeated creation. Because I don't think we can create two d2d
// and dwrite factory so we need to prevent the "probably dangerous" behavior.
@@ -76,31 +76,33 @@ DirectGraphFactory::DirectGraphFactory() {
&dwrite_system_font_collection_));
}
-DirectGraphFactory::~DirectGraphFactory() { UninitializeCom(); }
+DirectGraphicsFactory::~DirectGraphicsFactory() { UninitializeCom(); }
Microsoft::WRL::ComPtr<ID2D1DeviceContext>
-DirectGraphFactory::CreateD2D1DeviceContext() {
+DirectGraphicsFactory::CreateD2D1DeviceContext() {
Microsoft::WRL::ComPtr<ID2D1DeviceContext> d2d1_device_context;
ThrowIfFailed(d2d1_device_->CreateDeviceContext(
D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &d2d1_device_context));
return d2d1_device_context;
}
-std::unique_ptr<ISolidColorBrush> DirectGraphFactory::CreateSolidColorBrush() {
+std::unique_ptr<ISolidColorBrush>
+DirectGraphicsFactory::CreateSolidColorBrush() {
return std::make_unique<D2DSolidColorBrush>(this);
}
-std::unique_ptr<IGeometryBuilder> DirectGraphFactory::CreateGeometryBuilder() {
+std::unique_ptr<IGeometryBuilder>
+DirectGraphicsFactory::CreateGeometryBuilder() {
return std::make_unique<D2DGeometryBuilder>(this);
}
-std::unique_ptr<IFont> DirectGraphFactory::CreateFont(
- std::u16string font_family, float font_size) {
+std::unique_ptr<IFont> DirectGraphicsFactory::CreateFont(String font_family,
+ float font_size) {
return std::make_unique<DWriteFont>(this, std::move(font_family), font_size);
}
-std::unique_ptr<ITextLayout> DirectGraphFactory::CreateTextLayout(
- std::shared_ptr<IFont> font, std::u16string text) {
+std::unique_ptr<ITextLayout> DirectGraphicsFactory::CreateTextLayout(
+ std::shared_ptr<IFont> font, String text) {
return std::make_unique<DWriteTextLayout>(this, std::move(font),
std::move(text));
}
diff --git a/src/win/graphics/direct/Font.cpp b/src/win/graphics/direct/Font.cpp
index 1d6a5c88..413c998b 100644
--- a/src/win/graphics/direct/Font.cpp
+++ b/src/win/graphics/direct/Font.cpp
@@ -7,9 +7,9 @@
#include <utility>
namespace cru::platform::graphics::win::direct {
-DWriteFont::DWriteFont(DirectGraphFactory* factory, std::u16string font_family,
+DWriteFont::DWriteFont(DirectGraphicsFactory* factory, String font_family,
float font_size)
- : DirectGraphResource(factory), font_family_(std::move(font_family)) {
+ : DirectGraphicsResource(factory), font_family_(std::move(font_family)) {
// Get locale
std::array<wchar_t, LOCALE_NAME_MAX_LENGTH> buffer;
if (!::GetUserDefaultLocaleName(buffer.data(),
diff --git a/src/win/graphics/direct/Geometry.cpp b/src/win/graphics/direct/Geometry.cpp
index d07a819f..b37dd9f4 100644
--- a/src/win/graphics/direct/Geometry.cpp
+++ b/src/win/graphics/direct/Geometry.cpp
@@ -5,15 +5,15 @@
#include "cru/win/graphics/direct/Factory.hpp"
namespace cru::platform::graphics::win::direct {
-D2DGeometryBuilder::D2DGeometryBuilder(DirectGraphFactory* factory)
- : DirectGraphResource(factory) {
+D2DGeometryBuilder::D2DGeometryBuilder(DirectGraphicsFactory* factory)
+ : DirectGraphicsResource(factory) {
ThrowIfFailed(factory->GetD2D1Factory()->CreatePathGeometry(&geometry_));
ThrowIfFailed(geometry_->Open(&geometry_sink_));
}
void D2DGeometryBuilder::CheckValidation() {
if (!IsValid())
- throw ReuseException(L"The geometry builder is already disposed.");
+ throw ReuseException(u"The geometry builder is already disposed.");
}
void D2DGeometryBuilder::BeginFigure(const Point& point) {
@@ -49,9 +49,9 @@ std::unique_ptr<IGeometry> D2DGeometryBuilder::Build() {
return geometry;
}
-D2DGeometry::D2DGeometry(DirectGraphFactory* factory,
+D2DGeometry::D2DGeometry(DirectGraphicsFactory* factory,
Microsoft::WRL::ComPtr<ID2D1PathGeometry> geometry)
- : DirectGraphResource(factory), geometry_(std::move(geometry)) {}
+ : DirectGraphicsResource(factory), geometry_(std::move(geometry)) {}
bool D2DGeometry::FillContains(const Point& point) {
BOOL result;
diff --git a/src/win/graphics/direct/Painter.cpp b/src/win/graphics/direct/Painter.cpp
index 26ef92ec..1a43d1d0 100644
--- a/src/win/graphics/direct/Painter.cpp
+++ b/src/win/graphics/direct/Painter.cpp
@@ -27,6 +27,10 @@ void D2DPainter::SetTransform(const platform::Matrix& matrix) {
render_target_->SetTransform(Convert(matrix));
}
+void D2DPainter::ConcatTransform(const Matrix& matrix) {
+ SetTransform(GetTransform() * matrix);
+}
+
void D2DPainter::Clear(const Color& color) {
CheckValidation();
render_target_->Clear(Convert(color));
@@ -54,6 +58,24 @@ void D2DPainter::FillRectangle(const Rect& rectangle, IBrush* brush) {
render_target_->FillRectangle(Convert(rectangle), b->GetD2DBrushInterface());
}
+void D2DPainter::StrokeEllipse(const Rect& outline_rect, IBrush* brush,
+ float width) {
+ CheckValidation();
+ const auto b = CheckPlatform<ID2DBrush>(brush, GetPlatformId());
+ render_target_->DrawEllipse(
+ D2D1::Ellipse(Convert(outline_rect.GetCenter()),
+ outline_rect.width / 2.0f, outline_rect.height / 2.0f),
+ b->GetD2DBrushInterface(), width);
+}
+void D2DPainter::FillEllipse(const Rect& outline_rect, IBrush* brush) {
+ CheckValidation();
+ const auto b = CheckPlatform<ID2DBrush>(brush, GetPlatformId());
+ render_target_->FillEllipse(
+ D2D1::Ellipse(Convert(outline_rect.GetCenter()),
+ outline_rect.width / 2.0f, outline_rect.height / 2.0f),
+ b->GetD2DBrushInterface());
+}
+
void D2DPainter::StrokeGeometry(IGeometry* geometry, IBrush* brush,
float width) {
CheckValidation();
@@ -96,6 +118,24 @@ void D2DPainter::PopLayer() {
layers_.pop_back();
}
+void D2DPainter::PushState() {
+ Microsoft::WRL::ComPtr<ID2D1Factory> factory = nullptr;
+ render_target_->GetFactory(&factory);
+
+ Microsoft::WRL::ComPtr<ID2D1DrawingStateBlock> state_block;
+ factory->CreateDrawingStateBlock(&state_block);
+ render_target_->SaveDrawingState(state_block.Get());
+
+ drawing_state_stack_.push_back(std::move(state_block));
+}
+
+void D2DPainter::PopState() {
+ Expects(!drawing_state_stack_.empty());
+ auto drawing_state = drawing_state_stack_.back();
+ drawing_state_stack_.pop_back();
+ render_target_->RestoreDrawingState(drawing_state.Get());
+}
+
void D2DPainter::EndDraw() {
if (is_drawing_) {
is_drawing_ = false;
@@ -106,7 +146,7 @@ void D2DPainter::EndDraw() {
void D2DPainter::CheckValidation() {
if (!is_drawing_) {
throw cru::platform::ReuseException(
- L"Can't do that on painter after end drawing.");
+ u"Can't do that on painter after end drawing.");
}
}
} // namespace cru::platform::graphics::win::direct
diff --git a/src/win/graphics/direct/Resource.cpp b/src/win/graphics/direct/Resource.cpp
index 6ae74e64..0e9719f4 100644
--- a/src/win/graphics/direct/Resource.cpp
+++ b/src/win/graphics/direct/Resource.cpp
@@ -5,10 +5,12 @@
namespace cru::platform::graphics::win::direct {
String DirectResource::kPlatformId = u"Windows Direct";
-DirectGraphResource::DirectGraphResource(DirectGraphFactory* factory)
+DirectGraphicsResource::DirectGraphicsResource(DirectGraphicsFactory* factory)
: factory_(factory) {
Expects(factory);
}
-IGraphFactory* DirectGraphResource::GetGraphFactory() { return factory_; }
+IGraphicsFactory* DirectGraphicsResource::GetGraphicsFactory() {
+ return factory_;
+}
} // namespace cru::platform::graphics::win::direct
diff --git a/src/win/graphics/direct/TextLayout.cpp b/src/win/graphics/direct/TextLayout.cpp
index 0b3c68ca..bec4a972 100644
--- a/src/win/graphics/direct/TextLayout.cpp
+++ b/src/win/graphics/direct/TextLayout.cpp
@@ -1,4 +1,5 @@
#include "cru/win/graphics/direct/TextLayout.hpp"
+#include <dwrite.h>
#include "cru/common/Logger.hpp"
#include "cru/platform/Check.hpp"
@@ -9,10 +10,9 @@
#include <utility>
namespace cru::platform::graphics::win::direct {
-DWriteTextLayout::DWriteTextLayout(DirectGraphFactory* factory,
- std::shared_ptr<IFont> font,
- std::u16string text)
- : DirectGraphResource(factory), text_(std::move(text)) {
+DWriteTextLayout::DWriteTextLayout(DirectGraphicsFactory* factory,
+ std::shared_ptr<IFont> font, String text)
+ : DirectGraphicsResource(factory), text_(std::move(text)) {
Expects(font);
font_ = CheckPlatform<DWriteFont>(font, GetPlatformId());
@@ -24,12 +24,10 @@ DWriteTextLayout::DWriteTextLayout(DirectGraphFactory* factory,
DWriteTextLayout::~DWriteTextLayout() = default;
-std::u16string DWriteTextLayout::GetText() { return text_; }
+String DWriteTextLayout::GetText() { return text_; }
-std::u16string_view DWriteTextLayout::GetTextView() { return text_; }
-
-void DWriteTextLayout::SetText(std::u16string new_text) {
- text_.swap(new_text);
+void DWriteTextLayout::SetText(String new_text) {
+ text_ = std::move(new_text);
ThrowIfFailed(GetDirectFactory()->GetDWriteFactory()->CreateTextLayout(
reinterpret_cast<const wchar_t*>(text_.c_str()),
static_cast<UINT32>(text_.size()), font_->GetComInterface(), max_width_,
@@ -58,6 +56,44 @@ void DWriteTextLayout::SetMaxHeight(float max_height) {
ThrowIfFailed(text_layout_->SetMaxHeight(max_height_));
}
+bool DWriteTextLayout::IsEditMode() { return edit_mode_; }
+
+void DWriteTextLayout::SetEditMode(bool enable) {
+ edit_mode_ = enable;
+ // TODO: Implement this.
+}
+
+Index DWriteTextLayout::GetLineIndexFromCharIndex(Index char_index) {
+ if (char_index < 0 || char_index >= text_.size()) {
+ return -1;
+ }
+
+ auto line_index = 0;
+ for (Index i = 0; i < char_index; ++i) {
+ if (text_[i] == u'\n') {
+ line_index++;
+ }
+ }
+
+ return line_index;
+}
+
+float DWriteTextLayout::GetLineHeight(Index line_index) {
+ Index count = GetLineCount();
+ std::vector<DWRITE_LINE_METRICS> line_metrics(count);
+
+ UINT32 actual_line_count = 0;
+ text_layout_->GetLineMetrics(line_metrics.data(), static_cast<UINT32>(count),
+ &actual_line_count);
+ return line_metrics[line_index].height;
+}
+
+Index DWriteTextLayout::GetLineCount() {
+ UINT32 line_count = 0;
+ text_layout_->GetLineMetrics(nullptr, 0, &line_count);
+ return line_count;
+}
+
Rect DWriteTextLayout::GetTextBounds(bool includingTrailingSpace) {
DWRITE_TEXT_METRICS metrics;
ThrowIfFailed(text_layout_->GetMetrics(&metrics));
@@ -100,14 +136,14 @@ std::vector<Rect> DWriteTextLayout::TextRangeRect(
return result;
}
-Point DWriteTextLayout::TextSinglePoint(Index position, bool trailing) {
+Rect DWriteTextLayout::TextSinglePoint(Index position, bool trailing) {
DWRITE_HIT_TEST_METRICS metrics;
FLOAT left;
FLOAT top;
ThrowIfFailed(text_layout_->HitTestTextPosition(static_cast<UINT32>(position),
static_cast<BOOL>(trailing),
&left, &top, &metrics));
- return Point{left, top};
+ return Rect{left, top, 0, GetFont()->GetFontSize()};
}
TextHitTestResult DWriteTextLayout::HitTest(const Point& point) {
@@ -121,7 +157,6 @@ TextHitTestResult DWriteTextLayout::HitTest(const Point& point) {
TextHitTestResult result;
result.position = metrics.textPosition;
result.trailing = trailing != 0;
- result.insideText = inside != 0;
return result;
}
} // namespace cru::platform::graphics::win::direct
diff --git a/src/win/graphics/direct/WindowRenderTarget.cpp b/src/win/graphics/direct/WindowRenderTarget.cpp
index 7479ae24..020ce4b4 100644
--- a/src/win/graphics/direct/WindowRenderTarget.cpp
+++ b/src/win/graphics/direct/WindowRenderTarget.cpp
@@ -5,7 +5,7 @@
namespace cru::platform::graphics::win::direct {
D2DWindowRenderTarget::D2DWindowRenderTarget(
- gsl::not_null<DirectGraphFactory*> factory, HWND hwnd)
+ gsl::not_null<DirectGraphicsFactory*> factory, HWND hwnd)
: factory_(factory), hwnd_(hwnd) {
const auto d3d11_device = factory->GetD3D11Device();
const auto dxgi_factory = factory->GetDxgiFactory();