aboutsummaryrefslogtreecommitdiff
path: root/src/osx
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2021-10-31 22:53:11 +0800
committercrupest <crupest@outlook.com>2021-10-31 22:53:11 +0800
commit1dca2841da6f024f613d6dc16de456d5035f8fce (patch)
tree37ca6290afbe5900df2eb4a09e30024257d55316 /src/osx
parente68e0d9a5130e8bc0b634572b7fd44b9bfc0f8ef (diff)
downloadcru-1dca2841da6f024f613d6dc16de456d5035f8fce.tar.gz
cru-1dca2841da6f024f613d6dc16de456d5035f8fce.tar.bz2
cru-1dca2841da6f024f613d6dc16de456d5035f8fce.zip
...
Diffstat (limited to 'src/osx')
-rw-r--r--src/osx/graphics/quartz/Painter.cpp11
-rw-r--r--src/osx/graphics/quartz/TextLayout.cpp171
-rw-r--r--src/osx/gui/Window.mm15
3 files changed, 111 insertions, 86 deletions
diff --git a/src/osx/graphics/quartz/Painter.cpp b/src/osx/graphics/quartz/Painter.cpp
index 5657e048..798e1256 100644
--- a/src/osx/graphics/quartz/Painter.cpp
+++ b/src/osx/graphics/quartz/Painter.cpp
@@ -158,16 +158,7 @@ void QuartzCGContextPainter::DrawText(const Point& offset,
color = colors::black;
}
- auto bounds = tl->GetTextBounds();
-
- bounds.width += bounds.left;
- bounds.height += bounds.top;
- bounds.left = bounds.top = 0;
-
- Matrix transform =
- Matrix::Translation(-bounds.width / 2, -bounds.height / 2) *
- Matrix::Scale(1, -1) *
- Matrix::Translation(bounds.width / 2, bounds.height / 2);
+ Matrix transform = tl->GetTransform();
CGContextSaveGState(cg_context_);
diff --git a/src/osx/graphics/quartz/TextLayout.cpp b/src/osx/graphics/quartz/TextLayout.cpp
index 5145f9f9..d30c386f 100644
--- a/src/osx/graphics/quartz/TextLayout.cpp
+++ b/src/osx/graphics/quartz/TextLayout.cpp
@@ -72,83 +72,21 @@ void OsxCTTextLayout::SetMaxHeight(float max_height) {
}
Rect OsxCTTextLayout::GetTextBounds(bool includingTrailingSpace) {
- float left = std::numeric_limits<float>::max();
- float top = std::numeric_limits<float>::max();
- float right = 0;
- float bottom = 0;
-
- for (int i = 0; i < line_count_; i++) {
- auto line = lines_[i];
- const auto& line_origin = line_origins_[i];
-
- CGRect line_rect = CTLineGetImageBounds(line, nullptr);
- if (includingTrailingSpace) {
- float trailingWidth = CTLineGetTrailingWhitespaceWidth(line);
- line_rect.size.width += trailingWidth;
- }
-
- line_rect.origin.x += line_origin.x;
- line_rect.origin.y += line_origin.y;
-
- left = std::min<float>(line_rect.origin.x, left);
- top = std::min<float>(line_rect.origin.y, top);
- right = std::max<float>(line_rect.origin.x + line_rect.size.width, right);
- bottom =
- std::max<float>(line_rect.origin.y + line_rect.size.height, bottom);
- }
-
- return Rect::FromVertices(left, top, right, bottom);
+ return transform_.TransformRect(DoGetTextBounds(includingTrailingSpace));
}
std::vector<Rect> OsxCTTextLayout::TextRangeRect(const TextRange& text_range) {
- const auto r = text_.RangeFromCodeUnitToCodePoint(text_range).Normalize();
+ std::vector<Rect> results = DoTextRangeRect(text_range);
- std::vector<Rect> results;
-
- for (int i = 0; i < line_count_; i++) {
- auto line = lines_[i];
- const auto& line_origin = line_origins_[i];
-
- Range range = Convert(CTLineGetStringRange(line));
- range = range.CoerceInto(r.GetStart(), r.GetEnd());
-
- if (range.count) {
- auto line_rect = CTLineGetImageBounds(line, nullptr);
- line_rect.origin.x += line_origin.x;
- line_rect.origin.y += line_origin.y;
- float start_offset =
- CTLineGetOffsetForStringIndex(line, range.GetStart(), nullptr);
- float end_offset =
- CTLineGetOffsetForStringIndex(line, range.GetEnd(), nullptr);
- line_rect.origin.x += start_offset;
- line_rect.size.width = end_offset - start_offset;
- results.push_back(Convert(line_rect));
- }
+ for (auto& rect : results) {
+ rect = transform_.TransformRect(rect);
}
return results;
}
-Point OsxCTTextLayout::TextSinglePoint(Index position, bool trailing) {
- position = text_.IndexFromCodeUnitToCodePoint(position);
- for (int i = 0; i < line_count_; i++) {
- auto line = lines_[i];
- const auto& line_origin = line_origins_[i];
-
- Range range = Convert(CTLineGetStringRange(line));
- if (range.GetStart() <= position && position < range.GetEnd()) {
- auto offset = CTLineGetOffsetForStringIndex(line, position, nullptr);
- return Point(line_origin.x + offset, line_origin.y);
- } else if (position == range.GetEnd()) {
- return Point(
- line_origin.x + CTLineGetImageBounds(line, nullptr).size.width,
- line_origin.y);
- }
- }
-
- if (lines_.empty()) return Point{};
-
- return Convert(CTLineGetImageBounds(lines_.back(), nullptr)).GetRightTop();
+Rect OsxCTTextLayout::TextSinglePoint(Index position, bool trailing) {
+ return transform_.TransformRect(DoTextSinglePoint(position, trailing));
}
TextHitTestResult OsxCTTextLayout::HitTest(const Point& point) {
@@ -213,6 +151,13 @@ void OsxCTTextLayout::RecreateFrame() {
for (int i = 0; i < line_count_; i++) {
lines_[i] = static_cast<CTLineRef>(CFArrayGetValueAtIndex(lines, i));
}
+
+ auto bounds = DoGetTextBounds(false);
+
+ transform_ =
+ Matrix::Translation(-bounds.GetRight() / 2, -bounds.GetBottom() / 2) *
+ Matrix::Scale(1, -1) *
+ Matrix::Translation(bounds.GetRight() / 2, bounds.GetBottom() / 2);
}
CTFrameRef OsxCTTextLayout::CreateFrameWithColor(const Color& color) {
@@ -243,4 +188,94 @@ String OsxCTTextLayout::GetDebugString() {
max_height_);
}
+Rect OsxCTTextLayout::DoGetTextBounds(bool includingTrailingSpace) {
+ if (text_.empty()) return Rect{};
+
+ float left = std::numeric_limits<float>::max();
+ float top = std::numeric_limits<float>::max();
+ float right = 0;
+ float bottom = 0;
+
+ for (int i = 0; i < line_count_; i++) {
+ auto line = lines_[i];
+ const auto& line_origin = line_origins_[i];
+
+ CGRect line_rect = CTLineGetImageBounds(line, nullptr);
+ if (includingTrailingSpace) {
+ float trailingWidth = CTLineGetTrailingWhitespaceWidth(line);
+ line_rect.size.width += trailingWidth;
+ }
+
+ line_rect.origin.x += line_origin.x;
+ line_rect.origin.y += line_origin.y;
+
+ left = std::min<float>(line_rect.origin.x, left);
+ top = std::min<float>(line_rect.origin.y, top);
+ right = std::max<float>(line_rect.origin.x + line_rect.size.width, right);
+ bottom =
+ std::max<float>(line_rect.origin.y + line_rect.size.height, bottom);
+ }
+
+ return Rect::FromVertices(left, top, right, bottom);
+}
+
+std::vector<Rect> OsxCTTextLayout::DoTextRangeRect(
+ const TextRange& text_range) {
+ const auto r = text_.RangeFromCodeUnitToCodePoint(text_range).Normalize();
+
+ std::vector<Rect> results;
+
+ for (int i = 0; i < line_count_; i++) {
+ auto line = lines_[i];
+ const auto& line_origin = line_origins_[i];
+
+ Range range = Convert(CTLineGetStringRange(line));
+ range = range.CoerceInto(r.GetStart(), r.GetEnd());
+
+ if (range.count) {
+ auto line_rect = CTLineGetImageBounds(line, nullptr);
+ line_rect.origin.x += line_origin.x;
+ line_rect.origin.y += line_origin.y;
+ float start_offset =
+ CTLineGetOffsetForStringIndex(line, range.GetStart(), nullptr);
+ float end_offset =
+ CTLineGetOffsetForStringIndex(line, range.GetEnd(), nullptr);
+ line_rect.origin.x += start_offset;
+ line_rect.size.width = end_offset - start_offset;
+ results.push_back(Convert(line_rect));
+ }
+ }
+
+ return results;
+}
+
+Rect OsxCTTextLayout::DoTextSinglePoint(Index position, bool trailing) {
+ if (lines_.empty()) return Rect{0, 0, 0, font_->GetFontSize()};
+
+ position = text_.IndexFromCodeUnitToCodePoint(position);
+ for (int i = 0; i < line_count_; i++) {
+ auto line = lines_[i];
+ const auto& line_origin = line_origins_[i];
+
+ auto rect = Convert(CTLineGetImageBounds(line, nullptr));
+ rect.left += line_origin.x;
+ rect.top += line_origin.y;
+
+ Range range = Convert(CTLineGetStringRange(line));
+ if (range.GetStart() <= position && position < range.GetEnd()) {
+ auto offset = CTLineGetOffsetForStringIndex(line, position, nullptr);
+ return Rect(rect.left + offset, rect.top, 0, rect.height);
+ } else if (position == range.GetEnd()) {
+ return Rect(rect.GetRight(), rect.top, 0, rect.height);
+ }
+ }
+
+ // TODO: Complete logic here.
+
+ auto rect = Convert(CTLineGetImageBounds(lines_.back(), nullptr));
+ rect.left = rect.GetRight();
+ rect.width = 0;
+ return rect;
+}
+
} // namespace cru::platform::graphics::osx::quartz
diff --git a/src/osx/gui/Window.mm b/src/osx/gui/Window.mm
index 9a71d271..356c6be6 100644
--- a/src/osx/gui/Window.mm
+++ b/src/osx/gui/Window.mm
@@ -27,7 +27,6 @@
#include <Foundation/NSAttributedString.h>
#include <Foundation/NSString.h>
-#include <gsl/gsl_assert>
#include <limits>
#include <memory>
#include <unordered_set>
@@ -496,11 +495,11 @@ const std::unordered_set<KeyCode> bypass_codes{
auto ss = Convert(s);
- cru::log::TagDebug(u"CruView",
- u"Received setMarkedText string: {}, selected range: ({}, {}), "
- u"replacement range: ({}, {}).",
- ss, selectedRange.location, selectedRange.length, replacementRange.location,
- replacementRange.length);
+ // cru::log::TagDebug(u"CruView",
+ // u"Received setMarkedText string: {}, selected range: ({}, {}), "
+ // u"replacement range: ({}, {}).",
+ // ss, selectedRange.location, selectedRange.length, replacementRange.location,
+ // replacementRange.length);
if (_input_context_text == nil) {
_input_context_text = [[NSMutableAttributedString alloc] init];
@@ -557,8 +556,8 @@ const std::unordered_set<KeyCode> bypass_codes{
_input_context_p->SetCompositionText(cru::platform::gui::CompositionText());
cru::String ss = Convert(s);
- cru::log::TagDebug(u"CruView", u"Finish composition: {}, replacement range: ({}, {})", ss,
- replacementRange.location, replacementRange.length);
+ // cru::log::TagDebug(u"CruView", u"Finish composition: {}, replacement range: ({}, {})", ss,
+ // replacementRange.location, replacementRange.length);
_input_context_p->RaiseCompositionEvent();
_input_context_p->RaiseCompositionEndEvent();