diff options
author | crupest <crupest@outlook.com> | 2020-04-23 02:00:05 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2020-04-23 02:00:05 +0800 |
commit | 922d7f6c96f81a33538900f8a8992a5b6f640874 (patch) | |
tree | 71bd88e931137a23d4c4fcf7a27c55859ab5b0f4 | |
parent | f42531cc4c0f49451c4df30e4243e39581751215 (diff) | |
download | cru-922d7f6c96f81a33538900f8a8992a5b6f640874.tar.gz cru-922d7f6c96f81a33538900f8a8992a5b6f640874.tar.bz2 cru-922d7f6c96f81a33538900f8a8992a5b6f640874.zip |
...
-rw-r--r-- | include/cru/platform/graph_base.hpp | 9 | ||||
-rw-r--r-- | include/cru/ui/render/text_render_object.hpp | 2 | ||||
-rw-r--r-- | include/cru/win/graph/direct/text_layout.hpp | 2 | ||||
-rw-r--r-- | src/ui/render/text_render_object.cpp | 2 | ||||
-rw-r--r-- | src/win/graph/direct/text_layout.cpp | 8 |
5 files changed, 20 insertions, 3 deletions
diff --git a/include/cru/platform/graph_base.hpp b/include/cru/platform/graph_base.hpp index 0b997770..c880c7a2 100644 --- a/include/cru/platform/graph_base.hpp +++ b/include/cru/platform/graph_base.hpp @@ -229,6 +229,15 @@ struct TextRange final { gsl::index GetEnd() const { return position + count; } + TextRange Normalize() const { + auto result = *this; + if (result.count < 0) { + result.position += result.count; + result.count = -result.count; + } + return result; + } + gsl::index position = 0; gsl::index count = 0; }; diff --git a/include/cru/ui/render/text_render_object.hpp b/include/cru/ui/render/text_render_object.hpp index 1c472753..c062c9f0 100644 --- a/include/cru/ui/render/text_render_object.hpp +++ b/include/cru/ui/render/text_render_object.hpp @@ -27,7 +27,7 @@ class TextRenderObject : public RenderObject { void SetFont(std::shared_ptr<platform::graph::IFont> font); std::vector<Rect> TextRangeRect(const TextRange& text_range); - Point TextSingleRect(int position, bool trailing); + Point TextSingleRect(gsl::index position, bool trailing); platform::graph::TextHitTestResult TextHitTest(const Point& point); std::optional<TextRange> GetSelectionRange() const { diff --git a/include/cru/win/graph/direct/text_layout.hpp b/include/cru/win/graph/direct/text_layout.hpp index a9b89011..90faadf9 100644 --- a/include/cru/win/graph/direct/text_layout.hpp +++ b/include/cru/win/graph/direct/text_layout.hpp @@ -37,6 +37,8 @@ class DWriteTextLayout : public DirectGraphResource, void SetMaxHeight(float max_height) override; Rect GetTextBounds() override; + // Return empty vector if text_range.count is 0. Text range could be in + // reverse direction, it should be normalized first in implementation. std::vector<Rect> TextRangeRect(const TextRange& text_range) override; Point TextSingleRect(gsl::index position, bool trailing) override; TextHitTestResult HitTest(const Point& point) override; diff --git a/src/ui/render/text_render_object.cpp b/src/ui/render/text_render_object.cpp index be02f8fe..e8368480 100644 --- a/src/ui/render/text_render_object.cpp +++ b/src/ui/render/text_render_object.cpp @@ -50,7 +50,7 @@ std::vector<Rect> TextRenderObject::TextRangeRect(const TextRange& text_range) { return text_layout_->TextRangeRect(text_range); } -Point TextRenderObject::TextSingleRect(int position, bool trailing) { +Point TextRenderObject::TextSingleRect(gsl::index position, bool trailing) { return text_layout_->TextSingleRect(position, trailing); } diff --git a/src/win/graph/direct/text_layout.cpp b/src/win/graph/direct/text_layout.cpp index f582dd0a..4a742694 100644 --- a/src/win/graph/direct/text_layout.cpp +++ b/src/win/graph/direct/text_layout.cpp @@ -66,7 +66,13 @@ Rect DWriteTextLayout::GetTextBounds() { return Rect{metrics.left, metrics.top, metrics.width, metrics.height}; } -std::vector<Rect> DWriteTextLayout::TextRangeRect(const TextRange& text_range) { +std::vector<Rect> DWriteTextLayout::TextRangeRect( + const TextRange& text_range_arg) { + if (text_range_arg.count == 0) { + return {}; + } + const auto text_range = text_range_arg.Normalize(); + // TODO: This can be faster with one iteration. const int start_index = IndexUtf8ToUtf16(text_, static_cast<int>(text_range.position), w_text_); |