aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2021-11-01 22:16:24 +0800
committercrupest <crupest@outlook.com>2021-11-01 22:16:24 +0800
commit7045737332f742cec36c3d35f48fad82cd41a04b (patch)
treefe37c9cc781e728baa1db545529246578f232964 /src
parent1dca2841da6f024f613d6dc16de456d5035f8fce (diff)
downloadcru-7045737332f742cec36c3d35f48fad82cd41a04b.tar.gz
cru-7045737332f742cec36c3d35f48fad82cd41a04b.tar.bz2
cru-7045737332f742cec36c3d35f48fad82cd41a04b.zip
...
Diffstat (limited to 'src')
-rw-r--r--src/osx/graphics/quartz/TextLayout.cpp35
1 files changed, 31 insertions, 4 deletions
diff --git a/src/osx/graphics/quartz/TextLayout.cpp b/src/osx/graphics/quartz/TextLayout.cpp
index d30c386f..bdab1569 100644
--- a/src/osx/graphics/quartz/TextLayout.cpp
+++ b/src/osx/graphics/quartz/TextLayout.cpp
@@ -3,6 +3,7 @@
#include "cru/osx/graphics/quartz/Convert.hpp"
#include "cru/osx/graphics/quartz/Resource.hpp"
#include "cru/platform/Check.hpp"
+#include "cru/platform/graphics/Base.hpp"
#include <algorithm>
#include <limits>
@@ -94,13 +95,39 @@ TextHitTestResult OsxCTTextLayout::HitTest(const Point& point) {
auto line = lines_[i];
const auto& line_origin = line_origins_[i];
+ auto range =
+ text_.RangeFromCodePointToCodeUnit(Convert(CTLineGetStringRange(line)));
+
auto bounds = Convert(CTLineGetImageBounds(line, nullptr));
bounds.left += line_origin.x;
bounds.top += line_origin.y;
- if (bounds.IsPointInside(point)) {
- int position = CTLineGetStringIndexForPosition(
- line, CGPointMake(point.x - line_origin.x, point.y - line_origin.y));
- return TextHitTestResult{position, false, true};
+
+ bounds = transform_.TransformRect(bounds);
+
+ bool force_inside = false;
+ if (i == 0 && point.y < bounds.top) {
+ force_inside = true;
+ }
+
+ if (i == line_count_ - 1 && point.y >= bounds.GetBottom()) {
+ force_inside = true;
+ }
+
+ if (point.y >= bounds.top && point.y < bounds.GetBottom() || force_inside) {
+ auto p = point;
+ p.y = bounds.top;
+
+ if (p.x < bounds.left) {
+ return TextHitTestResult{range.position, false, false};
+ } else if (p.x > bounds.GetRight()) {
+ return TextHitTestResult{range.GetEnd(), false, false};
+ } else {
+ int position = CTLineGetStringIndexForPosition(
+ line, CGPointMake(p.x - line_origin.x, p.y - line_origin.y));
+ return TextHitTestResult{
+ text_.IndexFromCodePointToCodeUnit(position) + range.position,
+ false, true};
+ }
}
}