aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--demos/input_method/main.cpp49
-rw-r--r--include/cru/platform/graph/text_layout.hpp2
-rw-r--r--include/cru/platform/graph_base.hpp5
-rw-r--r--include/cru/win/graph/direct/text_layout.hpp2
-rw-r--r--src/win/graph/direct/text_layout.cpp2
5 files changed, 37 insertions, 23 deletions
diff --git a/demos/input_method/main.cpp b/demos/input_method/main.cpp
index ce96a8c1..ebca7a9d 100644
--- a/demos/input_method/main.cpp
+++ b/demos/input_method/main.cpp
@@ -33,6 +33,8 @@ int main() {
std::shared_ptr<IFont> font = graph_factory->CreateFont("等线", 30);
+ float window_width = 10000;
+
auto prompt_text_layout =
graph_factory->CreateTextLayout(font,
"Alt+F1: Enable IME\n"
@@ -40,29 +42,35 @@ int main() {
"Alt+F3: Complete composition.\n"
"Alt+F4: Cancel composition.");
- auto no_composition_text_layout =
- graph_factory->CreateTextLayout(font, "Not compositioning!");
-
std::optional<CompositionText> optional_composition_text;
std::string committed_text;
+ window->ResizeEvent()->AddHandler(
+ [&prompt_text_layout, &window_width](const Size& size) {
+ prompt_text_layout->SetMaxWidth(size.width);
+ window_width = size.width;
+ });
+
window->PaintEvent()->AddHandler([&](auto) {
auto painter = window->BeginPaint();
painter->Clear(colors::white);
painter->DrawText(Point{}, prompt_text_layout.get(), brush.get());
- auto anchor_y = prompt_text_layout->GetTextBounds().height;
+ const auto anchor_y = prompt_text_layout->GetTextBounds().height;
+
+ auto text_layout = graph_factory->CreateTextLayout(
+ font,
+ committed_text +
+ (optional_composition_text ? optional_composition_text->text : ""));
if (optional_composition_text) {
const auto& composition_text = *optional_composition_text;
- auto composition_text_layout =
- graph_factory->CreateTextLayout(font, composition_text.text);
for (int i = 0; i < composition_text.clauses.size(); i++) {
const auto& clause = composition_text.clauses[i];
- auto rects = composition_text_layout->TextRangeRect(
- TextRange::FromTwoSides(clause.start, clause.end));
+ auto rects = text_layout->TextRangeRect(TextRange::FromTwoSides(
+ clause.start, clause.end, committed_text.size()));
const auto& b = clause.target
? target_clause_brush
: (i % 2 ? odd_clause_brush : even_clause_brush);
@@ -71,22 +79,23 @@ int main() {
painter->FillRectangle(rect, b.get());
}
}
+ }
- painter->DrawText(Point{0, anchor_y}, composition_text_layout.get(),
- brush.get());
+ painter->DrawText(Point{0, anchor_y}, text_layout.get(), brush.get());
- anchor_y += composition_text_layout->GetTextBounds().height;
- } else {
- painter->DrawText(Point{0, anchor_y}, no_composition_text_layout.get(),
- brush.get());
- anchor_y += no_composition_text_layout->GetTextBounds().height;
- }
+ if (optional_composition_text) {
+ const auto& composition_text = *optional_composition_text;
- auto committed_text_layout =
- graph_factory->CreateTextLayout(font, committed_text);
+ const auto cursor_pos = composition_text.selection.position +
+ gsl::narrow_cast<int>(committed_text.size());
- painter->DrawText(Point{0, anchor_y}, committed_text_layout.get(),
- brush.get());
+ const auto cursor_lefttop =
+ text_layout->TextSingleRect(cursor_pos, false);
+
+ painter->FillRectangle(Rect{cursor_lefttop.x, cursor_lefttop.y + anchor_y,
+ 3, font->GetFontSize()},
+ brush.get());
+ }
});
window->KeyDownEvent()->AddHandler(
diff --git a/include/cru/platform/graph/text_layout.hpp b/include/cru/platform/graph/text_layout.hpp
index 20009c0d..0d104742 100644
--- a/include/cru/platform/graph/text_layout.hpp
+++ b/include/cru/platform/graph/text_layout.hpp
@@ -17,7 +17,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 Point TextSingleRect(gsl::index position, bool trailing) = 0;
virtual TextHitTestResult HitTest(const Point& point) = 0;
};
} // namespace cru::platform::graph
diff --git a/include/cru/platform/graph_base.hpp b/include/cru/platform/graph_base.hpp
index f25a7baf..0b997770 100644
--- a/include/cru/platform/graph_base.hpp
+++ b/include/cru/platform/graph_base.hpp
@@ -218,6 +218,11 @@ struct TextRange final {
return TextRange(start, end - start);
}
+ constexpr static TextRange FromTwoSides(gsl::index start, gsl::index end,
+ gsl::index offset) {
+ return TextRange(start + offset, end - start);
+ }
+
constexpr TextRange() = default;
constexpr TextRange(const gsl::index position, const gsl::index count = 0)
: position(position), count(count) {}
diff --git a/include/cru/win/graph/direct/text_layout.hpp b/include/cru/win/graph/direct/text_layout.hpp
index 462a5fd3..a9b89011 100644
--- a/include/cru/win/graph/direct/text_layout.hpp
+++ b/include/cru/win/graph/direct/text_layout.hpp
@@ -38,7 +38,7 @@ class DWriteTextLayout : public DirectGraphResource,
Rect GetTextBounds() override;
std::vector<Rect> TextRangeRect(const TextRange& text_range) override;
- Point TextSingleRect(int position, bool trailing) override;
+ Point TextSingleRect(gsl::index position, bool trailing) override;
TextHitTestResult HitTest(const Point& point) override;
private:
diff --git a/src/win/graph/direct/text_layout.cpp b/src/win/graph/direct/text_layout.cpp
index 6a6a2c45..f582dd0a 100644
--- a/src/win/graph/direct/text_layout.cpp
+++ b/src/win/graph/direct/text_layout.cpp
@@ -99,7 +99,7 @@ std::vector<Rect> DWriteTextLayout::TextRangeRect(const TextRange& text_range) {
return result;
}
-Point DWriteTextLayout::TextSingleRect(int position, bool trailing) {
+Point DWriteTextLayout::TextSingleRect(gsl::index position, bool trailing) {
const auto index =
IndexUtf8ToUtf16(text_, static_cast<int>(position), w_text_);