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

Fixes #2616. Support combining sequences that don't normalize. #3877

Draft
wants to merge 24 commits into
base: v2_develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
dbbe3f7
Fixes #2616. Support combining sequences that don't normalize.
BDisp Dec 3, 2024
cc5ca9e
Trying to deal with non-bmp.
BDisp Dec 5, 2024
42db5c9
Fix for WindowsDriver.
BDisp Dec 5, 2024
9b2f8b7
Re-enables ReplacementChar because it's more adequate.
BDisp Dec 5, 2024
84b337f
Prevents throwing an exception if the token was canceled after wait.
BDisp Dec 5, 2024
264cccb
Now it's rendering surrogate pairs better, but still needs to figure …
BDisp Dec 5, 2024
7d0a8c2
Merge branch 'v2_develop' into v2_2616_combining-marks
BDisp Dec 5, 2024
a25af7a
Merge branch 'v2_develop' into v2_2616_combining-marks
BDisp Dec 5, 2024
d5c7625
Remove unnecessary fields.
BDisp Dec 5, 2024
f95b237
Merge branch 'v2_develop' into v2_2616_combining-marks
tig Dec 5, 2024
0d4759c
Improve the NetDriver and CursesDriver.
BDisp Dec 5, 2024
9c0a2db
Merge branch 'v2_develop' into v2_2616_combining-marks
BDisp Dec 7, 2024
79746e9
Ensure using a valid cell to add combining marks.
BDisp Dec 8, 2024
d9e0ef6
Fix NetDriver and CursesDriver combining marks.
BDisp Dec 8, 2024
edd0545
Trying to fix WindowsDriver combining marks.
BDisp Dec 8, 2024
93d75c8
Add family glyph.
BDisp Dec 8, 2024
963797c
Remove unused variable.
BDisp Dec 8, 2024
519b452
Fix UnicodeCategory.Format with width zero because six columns can on…
BDisp Dec 8, 2024
b870647
Merge branch 'v2_develop' into v2_2616_combining-marks
BDisp Dec 13, 2024
17d3b0d
Fix combining marks issue if IgnoreIsCombiningMark is false.
BDisp Dec 13, 2024
7279a34
Fix combining marks in the Application.ToString method.
BDisp Dec 13, 2024
476a41d
Fix unit test that was sometime causing failure.
BDisp Dec 13, 2024
36f492f
Fix test that also was causing failing.
BDisp Dec 13, 2024
a9375e4
Always set ConsoleDriver.RunningUnitTests = true if Application.Init …
BDisp Dec 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ public void AddRune (Rune rune)
{
for (int i = Col; i > 0; i--)
{
if (!Contents [Row, i - 1].Rune.IsCombiningMark ())
if (!Contents [Row, i - 1].Rune.IsCombiningMark () && Contents [Row, i - 1].Rune.Value != ' ')
{
if (Contents [Row, i - 1].CombiningMarks is null)
{
Expand Down Expand Up @@ -282,13 +282,13 @@ public void AddRune (Rune rune)
{
Contents [Row, Col].Rune = rune;

if (Col < clipRect.Right - 1)
{
// Invalidate cell to right so that it doesn't get drawn
// TODO: Figure out if it is better to show a replacement character or ' '
Contents [Row, Col + 1].Rune = Rune.ReplacementChar;
Contents [Row, Col + 1].IsDirty = true;
}
//if (Col < clipRect.Right - 1)
//{
// // Invalidate cell to right so that it doesn't get drawn
// // TODO: Figure out if it is better to show a replacement character or ' '
// Contents [Row, Col + 1].Rune = Rune.ReplacementChar;
// Contents [Row, Col + 1].IsDirty = true;
//}
}
}
else
Expand Down
28 changes: 21 additions & 7 deletions Terminal.Gui/ConsoleDrivers/WindowsDriver/WindowsDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
private Point _pointMove;
private bool _processButtonClick;

public WindowsDriver ()

Check warning on line 43 in Terminal.Gui/ConsoleDrivers/WindowsDriver/WindowsDriver.cs

View workflow job for this annotation

GitHub Actions / build_release

Non-nullable field '_outputBuffer' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.

Check warning on line 43 in Terminal.Gui/ConsoleDrivers/WindowsDriver/WindowsDriver.cs

View workflow job for this annotation

GitHub Actions / build_and_test_debug (macos-latest)

Non-nullable field '_outputBuffer' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.

Check warning on line 43 in Terminal.Gui/ConsoleDrivers/WindowsDriver/WindowsDriver.cs

View workflow job for this annotation

GitHub Actions / build_and_test_debug (ubuntu-latest)

Non-nullable field '_outputBuffer' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.

Check warning on line 43 in Terminal.Gui/ConsoleDrivers/WindowsDriver/WindowsDriver.cs

View workflow job for this annotation

GitHub Actions / build_and_test_debug (windows-latest)

Non-nullable field '_outputBuffer' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.
{
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{
Expand Down Expand Up @@ -377,16 +377,30 @@
else
{
//_outputBuffer [position].Empty = true;
_outputBuffer [position].Char = (char)Rune.ReplacementChar.Value;
//_outputBuffer [position].Char = (char)Rune.ReplacementChar.Value;
var rune = Contents [row, col].Rune;
char [] surrogatePair = rune.ToString ().ToCharArray ();
Debug.Assert (surrogatePair.Length == 2);
_outputBuffer [position].Char = surrogatePair [0];

if (Contents [row, col].Rune.GetColumns () > 1 && col + 1 < Cols)
if (_outputBuffer [position].CombiningMarks == null)
{
_outputBuffer [position].CombiningMarks = [];
_outputBuffer [position].CombiningMarks!.Add (surrogatePair [1]);
}
else
{
// TODO: This is a hack to deal with non-BMP and wide characters.
col++;
position = row * Cols + col;
_outputBuffer [position].Empty = false;
_outputBuffer [position].Char = ' ';
_outputBuffer [position].CombiningMarks!.Insert (0, surrogatePair [1]);
}

//if (Contents [row, col].Rune.GetColumns () > 1 && col + 1 < Cols)
//{
// // TODO: This is a hack to deal with non-BMP and wide characters.
// col++;
// position = row * Cols + col;
// _outputBuffer [position].Empty = false;
// _outputBuffer [position].Char = ' ';
//}
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion Terminal.Gui/Text/RuneExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@ public static bool IsCombiningMark (this Rune rune)

return Rune.GetUnicodeCategory (rune) == UnicodeCategory.NonSpacingMark
|| category == UnicodeCategory.SpacingCombiningMark
|| category == UnicodeCategory.EnclosingMark;
|| category == UnicodeCategory.EnclosingMark
|| category == UnicodeCategory.Format;
}

/// <summary>Reports whether a rune is a surrogate code point.</summary>
Expand Down
65 changes: 37 additions & 28 deletions UICatalog/Scenarios/CombiningMarks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,34 +12,43 @@ public override void Main ()
var top = new Toplevel ();

top.DrawComplete += (s, e) =>
{
top.Move (0, 0);
top.AddStr ("Terminal.Gui only supports combining marks that normalize. See Issue #2616.");
top.Move (0, 2);
top.AddStr ("\u0301\u0301\u0328<- \"\\u0301\\u0301\\u0328]\" using AddStr.");
top.Move (0, 3);
top.AddStr ("[a\u0301\u0301\u0328]<- \"[a\\u0301\\u0301\\u0328]\" using AddStr.");
top.Move (0, 4);
top.AddRune ('[');
top.AddRune ('a');
top.AddRune ('\u0301');
top.AddRune ('\u0301');
top.AddRune ('\u0328');
top.AddRune (']');
top.AddStr ("<- \"[a\\u0301\\u0301\\u0328]\" using AddRune for each.");
top.Move (0, 6);
top.AddStr ("[e\u0301\u0301\u0328]<- \"[e\\u0301\\u0301\\u0328]\" using AddStr.");
top.Move (0, 7);
top.AddStr ("[e\u0301\u0328\u0301]<- \"[e\\u0301\\u0328\\u0301]\" using AddStr.");
top.Move (0, 8);
top.AddStr ("[e\u0328\u0301]<- \"[e\\u0328\\u0301]\" using AddStr.");
top.Move (0, 10);
top.AddStr ("From now on we are using Text Formatter");
TextFormatter tf = new () { Text = "[e\u0301\u0301\u0328]<- \"[e\\u0301\\u0301\\u0328]\" using TextFormatter." };
tf.Draw (new (0, 11, tf.Text.Length, 1), top.ColorScheme.Normal, top.ColorScheme.Normal);
tf.Text = "[e\u0328\u0301]<- \"[e\\u0328\\u0301]\" using TextFormatter.";
tf.Draw (new (0, 12, tf.Text.Length, 1), top.ColorScheme.Normal, top.ColorScheme.Normal);
};
{
var i = -1;
top.Move (0, ++i);
top.AddStr ("Terminal.Gui only supports combining marks that normalize. See Issue #2616.");
top.Move (0, ++i);
top.AddStr ("\u0301\u0301\u0328<- \"\\u0301\\u0301\\u0328]\" using AddStr.");
top.Move (0, ++i);
top.AddStr ("[a\u0301\u0301\u0328]<- \"[a\\u0301\\u0301\\u0328]\" using AddStr.");
top.Move (0, ++i);
top.AddRune ('[');
top.AddRune ('a');
top.AddRune ('\u0301');
top.AddRune ('\u0301');
top.AddRune ('\u0328');
top.AddRune (']');
top.AddStr ("<- \"[a\\u0301\\u0301\\u0328]\" using AddRune for each.");
top.Move (0, ++i + 1);
top.AddStr ("[e\u0301\u0301\u0328]<- \"[e\\u0301\\u0301\\u0328]\" using AddStr.");
top.Move (0, ++i);
top.AddStr ("[e\u0301\u0328\u0301]<- \"[e\\u0301\\u0328\\u0301]\" using AddStr.");
top.Move (0, ++i);
top.AddStr ("[e\u0328\u0301]<- \"[e\\u0328\\u0301]\" using AddStr.");
i++;
top.Move (0, ++i);
top.AddStr ("From now on we are using TextFormatter");
TextFormatter tf = new () { Text = "[e\u0301\u0301\u0328]<- \"[e\\u0301\\u0301\\u0328]\" using TextFormatter." };
tf.Draw (new (0, ++i, tf.Text.Length, 1), top.ColorScheme.Normal, top.ColorScheme.Normal);
tf.Text = "[e\u0328\u0301]<- \"[e\\u0328\\u0301]\" using TextFormatter.";
tf.Draw (new (0, ++i, tf.Text.Length, 1), top.ColorScheme.Normal, top.ColorScheme.Normal);
i++;
top.Move (0, ++i);
top.AddStr ("From now on we are using Surrogate pairs with combining diacritics");
top.Move (0, ++i);
top.AddStr ("[\ud835\udc4b\u0302]<- \"[\\ud835\\udc4b\\u0302]\" using AddStr.");
top.Move (0, ++i);
top.AddStr ("[\ud83e\uddd1\u200d\ud83e\uddd2]<- \"[\\ud83e\\uddd1\\u200d\\ud83e\\uddd2]\" using AddStr.");
};

Application.Run (top);
top.Dispose ();
Expand Down
Loading