-
Notifications
You must be signed in to change notification settings - Fork 84
Open
Description
Problem
When using CodeEditor.maxLengthSingleLineRendering, Re-Editor truncates a long single line by doing substring(0, N) on TextSpan.text / plainText. This counts UTF-16 code units and may cut in the middle of a grapheme cluster (surrogate pairs, ZWJ sequences, variation selectors).
This can lead to broken rendering (e.g. replacement character "�"), and potentially inconsistent caret/selection hit-testing near the truncation boundary.
Where
lib/src/_code_paragraph.dart:
// current implementation
if (renderingLength != null && plainText.length > renderingLength) {
impl = _build(trucate(span, renderingLength), plainText.substring(0, renderingLength), true);
}
TextSpan trucate(TextSpan span, int maxLength) {
// ...
if (text.length > remainingLength) {
text = text.substring(0, remainingLength);
}
// ...
}Repro
- Enable
wordWrap: true - Set
maxLengthSingleLineRenderingto a small number - Type/paste an emoji sequence around the boundary, e.g.:
- Surrogate pair:
😀 - ZWJ sequence:
👨👩👧👦or👩❤️💋👩
- Surrogate pair:
- If truncation cuts inside the sequence, rendering becomes broken.
Suggestion
Make truncation grapheme-safe:
- Use
package:characters(grapheme cluster iterator) to compute a safe prefix length <= maxLength (code units) and truncate at cluster boundaries. - Apply the same safe length to both the span truncation and the
plainTextsubstring.
This keeps the performance guard while avoiding invalid Unicode sequences.
Thanks!
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels