aboutsummaryrefslogtreecommitdiff
path: root/src/ui/render/text_render_object.cpp
blob: 49d7bcb4c0e41c9405aaed4c3beee8b35244352f (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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include "cru/ui/render/text_render_object.hpp"

#include "cru/platform/graph/graph_factory.hpp"
#include "cru/platform/graph/util/painter_util.hpp"
#include "cru/platform/graph/text_layout.hpp"

#include <algorithm>
#include <cassert>

namespace cru::ui::render {
TextRenderObject::TextRenderObject(
    std::shared_ptr<platform::graph::Brush> brush,
    std::shared_ptr<platform::graph::Font> font,
    std::shared_ptr<platform::graph::Brush> selection_brush) {
  assert(brush);
  assert(font);
  assert(selection_brush);

  SetChildMode(ChildMode::None);

  brush.swap(brush_);
  font.swap(font_);
  selection_brush.swap(selection_brush_);

  const auto graph_factory = platform::graph::GraphFactory::GetInstance();
  text_layout_.reset(graph_factory->CreateTextLayout(font_, L""));
}

std::wstring TextRenderObject::GetText() const {
  return text_layout_->GetText();
}

void TextRenderObject::SetText(std::wstring new_text) {
  text_layout_->SetText(std::move(new_text));
}

std::shared_ptr<platform::graph::Font> TextRenderObject::GetFont()
    const {
  return text_layout_->GetFont();
}

void TextRenderObject::SetFont(
    std::shared_ptr<platform::graph::Font> font) {
  text_layout_->SetFont(std::move(font));
}

void TextRenderObject::Draw(platform::graph::Painter* painter) {
  platform::graph::util::WithTransform(
      painter,
      platform::Matrix::Translation(GetMargin().left + GetPadding().left,
                                    GetMargin().top + GetPadding().top),
      [this](platform::graph::Painter* p) {
        if (this->selection_range_.has_value()) {
          const auto&& rects =
              text_layout_->TextRangeRect(this->selection_range_.value());
          for (const auto& rect : rects)
            p->FillRectangle(rect, this->GetSelectionBrush().get());
        }
        p->DrawText(Point{}, text_layout_.get(), brush_.get());
      });
}

RenderObject* TextRenderObject::HitTest(const Point& point) {
  const auto margin = GetMargin();
  const auto size = GetSize();
  return Rect{margin.left, margin.top,
              std::max(size.width - margin.GetHorizontalTotal(), 0.0f),
              std::max(size.height - margin.GetVerticalTotal(), 0.0f)}
                 .IsPointInside(point)
             ? this
             : nullptr;
}

void TextRenderObject::OnSizeChanged(const Size& old_size,
                                     const Size& new_size) {
  const auto&& size = GetContentRect().GetSize();
  text_layout_->SetMaxWidth(size.width);
  text_layout_->SetMaxHeight(size.height);
}

Size TextRenderObject::OnMeasureContent(const Size& available_size) {
  text_layout_->SetMaxWidth(available_size.width);
  text_layout_->SetMaxHeight(available_size.height);
  return text_layout_->GetTextBounds().GetSize();
}

void TextRenderObject::OnLayoutContent(const Rect& content_rect) {}
}  // namespace cru::ui::render