Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TextBox caret has incorrect position at the end of the string #12809

Open
HermanKirshin opened this issue Sep 7, 2023 · 6 comments
Open

TextBox caret has incorrect position at the end of the string #12809

HermanKirshin opened this issue Sep 7, 2023 · 6 comments
Labels

Comments

@HermanKirshin
Copy link
Contributor

Describe the bug
Caret in the end of the string overlaps letter

To Reproduce
Steps to reproduce the behavior:

  1. Create text box with Inter font and a bit smaller font size (i.e. 11.92)
  2. Write some text and compare caret position relative to letter in the end of the string and in the middle.
    <LayoutTransformControl> <LayoutTransformControl.LayoutTransform> <ScaleTransform ScaleX="5" ScaleY="5" /> </LayoutTransformControl.LayoutTransform> <TextBox FontFamily="avares://Avalonia.Fonts.Inter/Assets#Inter" FontSize="11.92" /> </LayoutTransformControl>

Expected behavior
Caret offset from letter is always the same

Screenshots
I applied x5 scaling to window for better visibility.

here you can see distance between number and caret
image

and here they overlap
image

Desktop (please complete the following information):

  • OS: Any
  • Version 11
@timunie
Copy link
Contributor

timunie commented Sep 7, 2023

@HermanKirshin we had this #12765 merged recently. Maybe you can test latest master (nightly) in order to check if that PR also fixes your issue. Thx 🙏

@HermanKirshin
Copy link
Contributor Author

HermanKirshin commented Sep 7, 2023

@timunie I had tested latest master and unfortunately no, issue still exists.

cursor

@Gillibald
Copy link
Contributor

https://github.com/AvaloniaUI/Avalonia/blob/master/src/Avalonia.Controls/Presenters/TextPresenter.cs#L410

@Gillibald
Copy link
Contributor

The issue is most likely that we can't draw outside the bounds of the control so we introduced this hack. We could either make the desired size of the TextPresenter slightly bigger or use the adorner layer to draw the caret.

@timunie
Copy link
Contributor

timunie commented Sep 7, 2023

@Gillibald I guess making it slightly bigger would be the better fix as otherwise one may have the caret sitting on the border

@HermanKirshin
Copy link
Contributor Author

@Gillibald Thank you, moving this code from GetCaretPoints to MeasureOverride with adding +1 to width solved the problem.


Index: src/Avalonia.Controls/Presenters/TextPresenter.cs
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/Avalonia.Controls/Presenters/TextPresenter.cs b/src/Avalonia.Controls/Presenters/TextPresenter.cs
--- a/src/Avalonia.Controls/Presenters/TextPresenter.cs	(revision fa8e1985f3e97e9d358130aaa19742834beacb7a)
+++ b/src/Avalonia.Controls/Presenters/TextPresenter.cs	(revision e8e0aa4c625f56d346b91e77813a2f0dc4675969)
@@ -401,15 +401,6 @@
             var y = Math.Floor(_caretBounds.Y) + 0.5;
             var b = Math.Ceiling(_caretBounds.Bottom) - 0.5;
 
-            var caretIndex = _lastCharacterHit.FirstCharacterIndex + _lastCharacterHit.TrailingLength;
-            var lineIndex = TextLayout.GetLineIndexFromCharacterIndex(caretIndex, _lastCharacterHit.TrailingLength > 0);
-            var textLine = TextLayout.TextLines[lineIndex];
-
-            if (_caretBounds.X > 0 && _caretBounds.X >= textLine.WidthIncludingTrailingWhitespace)
-            {
-                x -= 1;
-            }
-
             return (new Point(x, y), new Point(x, b));
         }
 
@@ -565,6 +556,15 @@
 
             var textWidth = TextLayout.OverhangLeading + TextLayout.WidthIncludingTrailingWhitespace + TextLayout.OverhangTrailing;
 
+            var caretIndex = _lastCharacterHit.FirstCharacterIndex + _lastCharacterHit.TrailingLength;
+            var lineIndex = TextLayout.GetLineIndexFromCharacterIndex(caretIndex, _lastCharacterHit.TrailingLength > 0);
+            var textLine = TextLayout.TextLines[lineIndex];
+
+            if (_caretBounds.X > 0 && _caretBounds.X >= textLine.WidthIncludingTrailingWhitespace)
+            {
+                textWidth += 1;
+            }
+
             return new Size(textWidth, TextLayout.Height);
         }
 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants