diff options
Diffstat (limited to 'src/win/graphics')
-rw-r--r-- | src/win/graphics/direct/Brush.cpp | 4 | ||||
-rw-r--r-- | src/win/graphics/direct/Factory.cpp | 20 | ||||
-rw-r--r-- | src/win/graphics/direct/Font.cpp | 4 | ||||
-rw-r--r-- | src/win/graphics/direct/Geometry.cpp | 10 | ||||
-rw-r--r-- | src/win/graphics/direct/Painter.cpp | 42 | ||||
-rw-r--r-- | src/win/graphics/direct/Resource.cpp | 6 | ||||
-rw-r--r-- | src/win/graphics/direct/TextLayout.cpp | 59 | ||||
-rw-r--r-- | src/win/graphics/direct/WindowRenderTarget.cpp | 2 |
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(); |