aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2020-03-01 22:32:58 +0800
committercrupest <crupest@outlook.com>2020-03-01 22:32:58 +0800
commitf23077eb0ddff77b7e114994f967189ea7607600 (patch)
tree9d27ccf8d721d40f8829ae2458e67a60eaaed25d
parent6e0e0e18cbeff6487160c84d71997575f6cccebd (diff)
downloadcru-f23077eb0ddff77b7e114994f967189ea7607600.tar.gz
cru-f23077eb0ddff77b7e114994f967189ea7607600.tar.bz2
cru-f23077eb0ddff77b7e114994f967189ea7607600.zip
Complete hit test in text layout.
-rw-r--r--include/cru/platform/graph/text_layout.hpp8
-rw-r--r--include/cru/win/graph/direct/text_layout.hpp2
-rw-r--r--src/win/graph/direct/text_layout.cpp38
3 files changed, 44 insertions, 4 deletions
diff --git a/include/cru/platform/graph/text_layout.hpp b/include/cru/platform/graph/text_layout.hpp
index 4f6e81e1..d1cfb44b 100644
--- a/include/cru/platform/graph/text_layout.hpp
+++ b/include/cru/platform/graph/text_layout.hpp
@@ -8,6 +8,12 @@
namespace cru::platform::graph {
struct IFont;
+struct TextHitTestResult {
+ int position;
+ bool trailing;
+ bool insideText;
+};
+
struct ITextLayout : virtual IGraphResource {
virtual std::string GetText() = 0;
virtual void SetText(std::string new_text) = 0;
@@ -20,5 +26,7 @@ struct ITextLayout : virtual IGraphResource {
virtual Rect GetTextBounds() = 0;
virtual std::vector<Rect> TextRangeRect(const TextRange& text_range) = 0;
+ virtual Point TextSingleRect(int position, bool trailing) = 0;
+ virtual TextHitTestResult HitTest(const Point& point) = 0;
};
} // namespace cru::platform::graph
diff --git a/include/cru/win/graph/direct/text_layout.hpp b/include/cru/win/graph/direct/text_layout.hpp
index 5a8f3f9c..5f7be9f3 100644
--- a/include/cru/win/graph/direct/text_layout.hpp
+++ b/include/cru/win/graph/direct/text_layout.hpp
@@ -38,6 +38,8 @@ class DWriteTextLayout : public DirectGraphResource,
Rect GetTextBounds() override;
std::vector<Rect> TextRangeRect(const TextRange& text_range) override;
+ Point TextSingleRect(int position, bool trailing) override;
+ TextHitTestResult HitTest(const Point& point) override;
private:
std::string text_;
diff --git a/src/win/graph/direct/text_layout.cpp b/src/win/graph/direct/text_layout.cpp
index a070d288..ecee1727 100644
--- a/src/win/graph/direct/text_layout.cpp
+++ b/src/win/graph/direct/text_layout.cpp
@@ -80,10 +80,10 @@ std::vector<Rect> DWriteTextLayout::TextRangeRect(const TextRange& text_range) {
std::vector<DWRITE_HIT_TEST_METRICS> hit_test_metrics(metrics_count);
UINT32 actual_count;
- text_layout_->HitTestTextRange(static_cast<UINT32>(start_index),
- static_cast<UINT32>(end_index - start_index),
- 0, 0, hit_test_metrics.data(), metrics_count,
- &actual_count);
+ ThrowIfFailed(text_layout_->HitTestTextRange(
+ static_cast<UINT32>(start_index),
+ static_cast<UINT32>(end_index - start_index), 0, 0,
+ hit_test_metrics.data(), metrics_count, &actual_count));
hit_test_metrics.erase(hit_test_metrics.cbegin() + actual_count,
hit_test_metrics.cend());
@@ -99,4 +99,34 @@ std::vector<Rect> DWriteTextLayout::TextRangeRect(const TextRange& text_range) {
return result;
}
+
+Point DWriteTextLayout::TextSingleRect(int position, bool trailing) {
+ const auto index =
+ IndexUtf8ToUtf16(text_, static_cast<int>(position), w_text_);
+
+ DWRITE_HIT_TEST_METRICS metrics;
+ FLOAT left;
+ FLOAT top;
+ ThrowIfFailed(text_layout_->HitTestTextPosition(static_cast<UINT32>(index),
+ static_cast<BOOL>(trailing),
+ &left, &top, &metrics));
+ return Point{left, top};
+}
+
+TextHitTestResult DWriteTextLayout::HitTest(const Point& point) {
+ BOOL trailing;
+ BOOL inside;
+ DWRITE_HIT_TEST_METRICS metrics;
+
+ ThrowIfFailed(text_layout_->HitTestPoint(point.x, point.y, &trailing, &inside,
+ &metrics));
+
+ const auto index =
+ IndexUtf16ToUtf8(w_text_, static_cast<int>(metrics.textPosition), text_);
+ TextHitTestResult result;
+ result.position = index;
+ result.trailing = trailing != 0;
+ result.insideText = inside != 0;
+ return result;
+}
} // namespace cru::platform::graph::win::direct