aboutsummaryrefslogtreecommitdiff
path: root/src/win/graph/win_geometry.cpp
blob: a725eff6d309b0c21595699ad4c1a64ddeeaf60c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include "cru/win/graph/win_geometry.hpp"

#include "cru/win/exception.hpp"
#include "cru/win/graph/util/convert_util.hpp"
#include "cru/win/graph/win_native_factory.hpp"

#include <cassert>

namespace cru::win::graph {
WinGeometryBuilder::WinGeometryBuilder(IWinNativeFactory* factory) {
  assert(factory);
  ThrowIfFailed(factory->GetD2D1Factory()->CreatePathGeometry(&geometry_));
  ThrowIfFailed(geometry_->Open(&geometry_sink_));
}

WinGeometryBuilder::~WinGeometryBuilder() {
  if (geometry_sink_) {
    ThrowIfFailed(geometry_sink_->Close());
  }
}

void WinGeometryBuilder::BeginFigure(const ui::Point& point) {
  assert(IsEnded());
  geometry_sink_->BeginFigure(util::Convert(point), D2D1_FIGURE_BEGIN_FILLED);
}

void WinGeometryBuilder::LineTo(const ui::Point& point) {
  assert(IsEnded());
  geometry_sink_->AddLine(util::Convert(point));
}

void WinGeometryBuilder::QuadraticBezierTo(const ui::Point& control_point,
                                           const ui::Point& end_point) {
  assert(IsEnded());
  geometry_sink_->AddQuadraticBezier(D2D1::QuadraticBezierSegment(
      util::Convert(control_point), util::Convert(end_point)));
}

void WinGeometryBuilder::CloseFigure(bool close) {
  assert(IsEnded());
  geometry_sink_->EndFigure(close ? D2D1_FIGURE_END_CLOSED
                                  : D2D1_FIGURE_END_OPEN);
}

platform::graph::IGeometry* WinGeometryBuilder::End() {
  assert(IsEnded());
  ThrowIfFailed(geometry_sink_->Close());
  geometry_sink_ = nullptr;
  const auto geometry = new WinGeometry(std::move(geometry_));
  geometry_ = nullptr;
  return geometry;
}

WinGeometry::WinGeometry(Microsoft::WRL::ComPtr<ID2D1PathGeometry> geometry) {
  assert(geometry);
  geometry_ = std::move(geometry);
}

bool WinGeometry::FillContains(const ui::Point& point) {
  BOOL result;
  ThrowIfFailed(geometry_->FillContainsPoint(
      util::Convert(point), D2D1::Matrix3x2F::Identity(), &result));
  return result != 0;
}
}  // namespace cru::win::graph