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
Improve long lines support #172
Conversation
Avalonia's FormattedText measuring starts to accumulate error when measuring glyphs aprox at index 3000. Splitting the VisualLine in chunks of 3000 characters fixes that. Additionally, editing, selection and navigation performance is better if we split the line in smaller chunks.
…g lines Two changes here: 1) Do not calculate all the glyph widths at the beginning. Calculating them under demand allows us to improve performance thanks to the virtualization of the ScrollViewer. 2) Measure each glyph for long lines kills performance. So, as an improvement, when using a monospaced font, if we detect a long chunk (>3000 characters), just assign the same width for all glyphs.
src/AvaloniaEdit/Text/TextLineRun.cs
Outdated
|
||
double MeasureGlyphAt(int index) | ||
{ | ||
return new FormattedText |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should rewrite this to use the current platform's method of measuring a character and avoid constructing a FormattedText instance for every character.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Gillibald, thank you for your comments. I would just to clarify... What do you exactly mean?
- Avalonia already implements something to get all the glyph widths?
- We should call
SKPaint.GetGlyphWidths
directly from AvaloniaEdit? - We should implement some API in Avalonia to get the glyph widths from
SKPaint.GetGlyphWidths
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avalonia already supports getting a glyph's width via GlyphTypeface so we might just be able to use that API.
I have added this code lately and it should work for all platforms.
https://github.com/AvaloniaUI/Avalonia/blob/master/src/Skia/Avalonia.Skia/FormattedTextImpl.cs#L715
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@HendrikMennen thanks for reporting. Yes, you're right. The failing code was added on this PR. It seems under some scenarios there is an issue measuring the glyph widths. Please, file a new issue, including a consistent repro case, and I'll try to fix it. |
This PR allows AvaloniaEdit to handle long lines with acceptable performance.
Before this PR, AvaloniaEdit only supported lines no longer than 10.000 characters. If a line in the document was longer than 10.000 characters, an exception was raised.
Previous issues handling long lines
Before this PR, removing that restriction, AvaloniaEdit is able to display longer lines, but some issues appear:
Changes made to support long lines
I made several changes to better support very long lines:
FormattedText
measuring accumulates error when measuring glyphs approx above index 3000. Splitting the VisualLine in chunks of 3000 characters fixes the issue.VisualLineElementGenerators
for long lines: Some generators, such as the one that detects email addresses or hyperlinks that let the user click to open the link, performed badly with long lines because they use regular expressions.Demo video handling long lines
I created a file with a really huge line (~5 million column). After this PR changes, AvaloniaEdit is able to deal with it.
avaloniaedit-huge-line.mov