diff options
Diffstat (limited to 'src/ui/render/text_render_object.cpp')
-rw-r--r-- | src/ui/render/text_render_object.cpp | 151 |
1 files changed, 45 insertions, 106 deletions
diff --git a/src/ui/render/text_render_object.cpp b/src/ui/render/text_render_object.cpp index 69563ad7..bdf48c9a 100644 --- a/src/ui/render/text_render_object.cpp +++ b/src/ui/render/text_render_object.cpp @@ -1,103 +1,61 @@ -#include "text_render_object.hpp" +#include "cru/ui/render/text_render_object.hpp" -#include <d2d1.h> -#include <dwrite.h> -#include <algorithm> +#include "cru/platform/graph_factory.hpp" +#include "cru/platform/painter_util.hpp" +#include "cru/platform/text_layout.hpp" +#include "cru/platform/ui_applicaition.hpp" -#include "exception.hpp" -#include "graph/graph_manager.hpp" -#include "graph/graph_util.hpp" -#include "util/com_util.hpp" +#include <algorithm> +#include <cassert> namespace cru::ui::render { -TextRenderObject::TextRenderObject(ID2D1Brush* brush, IDWriteTextFormat* format, - ID2D1Brush* selection_brush) { +TextRenderObject::TextRenderObject( + std::shared_ptr<platform::Brush> brush, + std::shared_ptr<platform::FontDescriptor> font, + std::shared_ptr<platform::Brush> selection_brush) { assert(brush); - assert(format); + assert(font); 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_); -} + brush.swap(brush_); + font.swap(font_); + selection_brush.swap(selection_brush_); -void TextRenderObject::SetBrush(ID2D1Brush* new_brush) { - assert(new_brush); - util::SafeRelease(brush_); - new_brush->AddRef(); - brush_ = new_brush; -} + const auto graph_factory = + platform::UiApplication::GetInstance()->GetGraphFactory(); -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(); + text_layout_.reset(graph_factory->CreateTextLayout(font_, L"")); } -void TextRenderObject::SetSelectionBrush(ID2D1Brush* new_brush) { - assert(new_brush); - util::SafeRelease(selection_brush_); - new_brush->AddRef(); - selection_brush_ = new_brush; +std::wstring TextRenderObject::GetText() const { + return text_layout_->GetText(); } -namespace { -void DrawSelectionRect(ID2D1RenderTarget* render_target, - IDWriteTextLayout* layout, ID2D1Brush* brush, - const std::optional<TextRange> range) { - if (range.has_value()) { - DWRITE_TEXT_METRICS text_metrics{}; - ThrowIfFailed(layout->GetMetrics(&text_metrics)); - const auto metrics_count = - text_metrics.lineCount * text_metrics.maxBidiReorderingDepth; - - std::vector<DWRITE_HIT_TEST_METRICS> hit_test_metrics(metrics_count); - UINT32 actual_count; - layout->HitTestTextRange(range.value().position, range.value().count, 0, 0, - hit_test_metrics.data(), metrics_count, - &actual_count); +void TextRenderObject::SetText(std::wstring new_text) { + text_layout_->SetText(std::move(new_text)); +} - hit_test_metrics.erase(hit_test_metrics.cbegin() + actual_count, - hit_test_metrics.cend()); +std::shared_ptr<platform::FontDescriptor> TextRenderObject::GetFont() const { + return text_layout_->GetFont(); +} - for (const auto& metrics : hit_test_metrics) - render_target->FillRoundedRectangle( - D2D1::RoundedRect(D2D1::RectF(metrics.left, metrics.top, - metrics.left + metrics.width, - metrics.top + metrics.height), - 3, 3), - brush); - } +void TextRenderObject::SetFont(std::shared_ptr<platform::FontDescriptor> font) { + text_layout_->SetFont(std::move(font)); } -} // namespace -void TextRenderObject::Draw(ID2D1RenderTarget* render_target) { - graph::WithTransform( - render_target, - D2D1::Matrix3x2F::Translation(GetMargin().left + GetPadding().left, +void TextRenderObject::Draw(platform::Painter* painter) { + platform::util::WithTransform( + painter, + platform::Matrix::Translation(GetMargin().left + GetPadding().left, GetMargin().top + GetPadding().top), - [this](auto rt) { - DrawSelectionRect(rt, text_layout_, selection_brush_, selection_range_); - rt->DrawTextLayout(D2D1::Point2F(), text_layout_, brush_); + [this](platform::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()); }); } @@ -115,34 +73,15 @@ RenderObject* TextRenderObject::HitTest(const Point& point) { void TextRenderObject::OnSizeChanged(const Size& old_size, const Size& new_size) { const auto&& size = GetContentRect().GetSize(); - ThrowIfFailed(text_layout_->SetMaxWidth(size.width)); - ThrowIfFailed(text_layout_->SetMaxHeight(size.height)); + text_layout_->SetMaxWidth(size.width); + text_layout_->SetMaxHeight(size.height); } Size TextRenderObject::OnMeasureContent(const Size& available_size) { - ThrowIfFailed(text_layout_->SetMaxWidth(available_size.width)); - ThrowIfFailed(text_layout_->SetMaxHeight(available_size.height)); - - DWRITE_TEXT_METRICS metrics; - ThrowIfFailed(text_layout_->GetMetrics(&metrics)); - - return Size(metrics.width, metrics.height); + text_layout_->SetMaxWidth(available_size.width); + text_layout_->SetMaxHeight(available_size.height); + return text_layout_->GetTextBounds().GetSize(); } void TextRenderObject::OnLayoutContent(const Rect& content_rect) {} - -void TextRenderObject::RecreateTextLayout() { - assert(text_format_ != nullptr); - - util::SafeRelease(text_layout_); - - const auto dwrite_factory = - graph::GraphManager::GetInstance()->GetDWriteFactory(); - - const auto&& size = GetContentRect().GetSize(); - - ThrowIfFailed(dwrite_factory->CreateTextLayout( - text_.c_str(), static_cast<UINT32>(text_.size()), text_format_, - size.width, size.height, &text_layout_)); -} } // namespace cru::ui::render |