Merge pull request #2318 from BDisp/normalize-drivers-fix_2317

Fixes #2317. Drivers do not normalize accented letters.
This commit is contained in:
Tig
2023-02-06 07:17:31 +09:00
committed by GitHub
5 changed files with 166 additions and 90 deletions

View File

@@ -62,40 +62,59 @@ namespace Terminal.Gui {
Curses.move (crow, ccol);
needMove = false;
}
if (runeWidth < 2 && ccol > 0
&& Rune.ColumnWidth ((char)contents [crow, ccol - 1, 0]) > 1) {
if (runeWidth == 0 && ccol > 0) {
var r = contents [crow, ccol - 1, 0];
var s = new string (new char [] { (char)r, (char)rune });
string sn;
if (!s.IsNormalized ()) {
sn = s.Normalize ();
} else {
sn = s;
}
var c = sn [0];
Curses.mvaddch (crow, ccol - 1, (int)(uint)c);
contents [crow, ccol - 1, 0] = c;
contents [crow, ccol - 1, 1] = currentAttribute;
contents [crow, ccol - 1, 2] = 1;
var curAtttib = currentAttribute;
Curses.attrset (contents [crow, ccol - 1, 1]);
Curses.mvaddch (crow, ccol - 1, (int)(uint)' ');
contents [crow, ccol - 1, 0] = (int)(uint)' ';
Curses.move (crow, ccol);
Curses.attrset (curAtttib);
} else if (runeWidth < 2 && ccol <= Clip.Right - 1
&& Rune.ColumnWidth ((char)contents [crow, ccol, 0]) > 1) {
var curAtttib = currentAttribute;
Curses.attrset (contents [crow, ccol + 1, 1]);
Curses.mvaddch (crow, ccol + 1, (int)(uint)' ');
contents [crow, ccol + 1, 0] = (int)(uint)' ';
Curses.move (crow, ccol);
Curses.attrset (curAtttib);
}
if (runeWidth > 1 && ccol == Clip.Right - 1) {
Curses.addch ((int)(uint)' ');
contents [crow, ccol, 0] = (int)(uint)' ';
} else {
Curses.addch ((int)(uint)rune);
contents [crow, ccol, 0] = (int)(uint)rune;
if (runeWidth < 2 && ccol > 0
&& Rune.ColumnWidth ((char)contents [crow, ccol - 1, 0]) > 1) {
var curAtttib = currentAttribute;
Curses.attrset (contents [crow, ccol - 1, 1]);
Curses.mvaddch (crow, ccol - 1, (int)(uint)' ');
contents [crow, ccol - 1, 0] = (int)(uint)' ';
Curses.move (crow, ccol);
Curses.attrset (curAtttib);
} else if (runeWidth < 2 && ccol <= Clip.Right - 1
&& Rune.ColumnWidth ((char)contents [crow, ccol, 0]) > 1) {
var curAtttib = currentAttribute;
Curses.attrset (contents [crow, ccol + 1, 1]);
Curses.mvaddch (crow, ccol + 1, (int)(uint)' ');
contents [crow, ccol + 1, 0] = (int)(uint)' ';
Curses.move (crow, ccol);
Curses.attrset (curAtttib);
}
if (runeWidth > 1 && ccol == Clip.Right - 1) {
Curses.addch ((int)(uint)' ');
contents [crow, ccol, 0] = (int)(uint)' ';
} else {
Curses.addch ((int)(uint)rune);
contents [crow, ccol, 0] = (int)(uint)rune;
}
contents [crow, ccol, 1] = currentAttribute;
contents [crow, ccol, 2] = 1;
}
contents [crow, ccol, 1] = currentAttribute;
contents [crow, ccol, 2] = 1;
} else
needMove = true;
ccol++;
if (runeWidth < 0 || runeWidth > 0) {
ccol++;
}
if (runeWidth > 1) {
if (validClip && ccol < Clip.Right) {
contents [crow, ccol, 1] = currentAttribute;

View File

@@ -33,7 +33,7 @@ namespace Terminal.Gui {
UseFakeClipboard = useFakeClipboard;
FakeClipboardAlwaysThrowsNotSupportedException = fakeClipboardAlwaysThrowsNotSupportedException;
FakeClipboardIsSupportedAlwaysFalse = fakeClipboardIsSupportedAlwaysTrue;
// double check usage is correct
Debug.Assert (useFakeClipboard == false && fakeClipboardAlwaysThrowsNotSupportedException == false);
Debug.Assert (useFakeClipboard == false && fakeClipboardIsSupportedAlwaysTrue == false);
@@ -131,31 +131,49 @@ namespace Terminal.Gui {
//MockConsole.CursorTop = crow;
needMove = false;
}
if (runeWidth < 2 && ccol > 0
if (runeWidth == 0 && ccol > 0) {
var r = contents [crow, ccol - 1, 0];
var s = new string (new char [] { (char)r, (char)rune });
string sn;
if (!s.IsNormalized ()) {
sn = s.Normalize ();
} else {
sn = s;
}
var c = sn [0];
contents [crow, ccol - 1, 0] = c;
contents [crow, ccol - 1, 1] = currentAttribute;
contents [crow, ccol - 1, 2] = 1;
} else {
if (runeWidth < 2 && ccol > 0
&& Rune.ColumnWidth ((Rune)contents [crow, ccol - 1, 0]) > 1) {
contents [crow, ccol - 1, 0] = (int)(uint)' ';
contents [crow, ccol - 1, 0] = (int)(uint)' ';
} else if (runeWidth < 2 && ccol <= Clip.Right - 1
&& Rune.ColumnWidth ((Rune)contents [crow, ccol, 0]) > 1) {
} else if (runeWidth < 2 && ccol <= Clip.Right - 1
&& Rune.ColumnWidth ((Rune)contents [crow, ccol, 0]) > 1) {
contents [crow, ccol + 1, 0] = (int)(uint)' ';
contents [crow, ccol + 1, 2] = 1;
contents [crow, ccol + 1, 0] = (int)(uint)' ';
contents [crow, ccol + 1, 2] = 1;
}
if (runeWidth > 1 && ccol == Clip.Right - 1) {
contents [crow, ccol, 0] = (int)(uint)' ';
} else {
contents [crow, ccol, 0] = (int)(uint)rune;
}
contents [crow, ccol, 1] = currentAttribute;
contents [crow, ccol, 2] = 1;
dirtyLine [crow] = true;
}
if (runeWidth > 1 && ccol == Clip.Right - 1) {
contents [crow, ccol, 0] = (int)(uint)' ';
} else {
contents [crow, ccol, 0] = (int)(uint)rune;
}
contents [crow, ccol, 1] = currentAttribute;
contents [crow, ccol, 2] = 1;
dirtyLine [crow] = true;
} else
needMove = true;
ccol++;
if (runeWidth < 0 || runeWidth > 0) {
ccol++;
}
if (runeWidth > 1) {
if (validClip && ccol < Clip.Right) {
contents [crow, ccol, 1] = currentAttribute;

View File

@@ -1241,30 +1241,48 @@ namespace Terminal.Gui {
var validClip = IsValidContent (ccol, crow, Clip);
if (validClip) {
if (runeWidth < 2 && ccol > 0
&& Rune.ColumnWidth ((char)contents [crow, ccol - 1, 0]) > 1) {
if (runeWidth == 0 && ccol > 0) {
var r = contents [crow, ccol - 1, 0];
var s = new string (new char [] { (char)r, (char)rune });
string sn;
if (!s.IsNormalized ()) {
sn = s.Normalize ();
} else {
sn = s;
}
var c = sn [0];
contents [crow, ccol - 1, 0] = c;
contents [crow, ccol - 1, 1] = currentAttribute;
contents [crow, ccol - 1, 2] = 1;
contents [crow, ccol - 1, 0] = (int)(uint)' ';
} else if (runeWidth < 2 && ccol <= Clip.Right - 1
&& Rune.ColumnWidth ((char)contents [crow, ccol, 0]) > 1) {
contents [crow, ccol + 1, 0] = (int)(uint)' ';
contents [crow, ccol + 1, 2] = 1;
}
if (runeWidth > 1 && ccol == Clip.Right - 1) {
contents [crow, ccol, 0] = (int)(uint)' ';
} else {
contents [crow, ccol, 0] = (int)(uint)rune;
}
contents [crow, ccol, 1] = currentAttribute;
contents [crow, ccol, 2] = 1;
if (runeWidth < 2 && ccol > 0
&& Rune.ColumnWidth ((char)contents [crow, ccol - 1, 0]) > 1) {
contents [crow, ccol - 1, 0] = (int)(uint)' ';
} else if (runeWidth < 2 && ccol <= Clip.Right - 1
&& Rune.ColumnWidth ((char)contents [crow, ccol, 0]) > 1) {
contents [crow, ccol + 1, 0] = (int)(uint)' ';
contents [crow, ccol + 1, 2] = 1;
}
if (runeWidth > 1 && ccol == Clip.Right - 1) {
contents [crow, ccol, 0] = (int)(uint)' ';
} else {
contents [crow, ccol, 0] = (int)(uint)rune;
}
contents [crow, ccol, 1] = currentAttribute;
contents [crow, ccol, 2] = 1;
}
dirtyLine [crow] = true;
}
ccol++;
if (runeWidth < 0 || runeWidth > 0) {
ccol++;
}
if (runeWidth > 1) {
if (validClip && ccol < Clip.Right) {
contents [crow, ccol, 1] = currentAttribute;
@@ -1485,7 +1503,7 @@ namespace Terminal.Gui {
outputWidth++;
var rune = contents [row, col, 0];
char [] spair;
if (Rune.DecodeSurrogatePair((uint) rune, out spair)) {
if (Rune.DecodeSurrogatePair ((uint)rune, out spair)) {
output.Append (spair);
} else {
output.Append ((char)rune);

View File

@@ -1517,35 +1517,56 @@ namespace Terminal.Gui {
var validClip = IsValidContent (ccol, crow, Clip);
if (validClip) {
if (runeWidth < 2 && ccol > 0
&& Rune.ColumnWidth ((char)contents [crow, ccol - 1, 0]) > 1) {
if (runeWidth == 0 && ccol > 0) {
var r = contents [crow, ccol - 1, 0];
var s = new string (new char [] { (char)r, (char)rune });
string sn;
if (!s.IsNormalized ()) {
sn = s.Normalize ();
} else {
sn = s;
}
var c = sn [0];
var prevPosition = crow * Cols + (ccol - 1);
OutputBuffer [prevPosition].Char.UnicodeChar = ' ';
contents [crow, ccol - 1, 0] = (int)(uint)' ';
} else if (runeWidth < 2 && ccol <= Clip.Right - 1
&& Rune.ColumnWidth ((char)contents [crow, ccol, 0]) > 1) {
var prevPosition = GetOutputBufferPosition () + 1;
OutputBuffer [prevPosition].Char.UnicodeChar = (char)' ';
contents [crow, ccol + 1, 0] = (int)(uint)' ';
}
if (runeWidth > 1 && ccol == Clip.Right - 1) {
OutputBuffer [position].Char.UnicodeChar = (char)' ';
contents [crow, ccol, 0] = (int)(uint)' ';
OutputBuffer [prevPosition].Char.UnicodeChar = c;
contents [crow, ccol - 1, 0] = c;
OutputBuffer [prevPosition].Attributes = (ushort)currentAttribute;
contents [crow, ccol - 1, 1] = currentAttribute;
contents [crow, ccol - 1, 2] = 1;
WindowsConsole.SmallRect.Update (ref damageRegion, (short)(ccol - 1), (short)crow);
} else {
OutputBuffer [position].Char.UnicodeChar = (char)rune;
contents [crow, ccol, 0] = (int)(uint)rune;
if (runeWidth < 2 && ccol > 0
&& Rune.ColumnWidth ((char)contents [crow, ccol - 1, 0]) > 1) {
var prevPosition = crow * Cols + (ccol - 1);
OutputBuffer [prevPosition].Char.UnicodeChar = ' ';
contents [crow, ccol - 1, 0] = (int)(uint)' ';
} else if (runeWidth < 2 && ccol <= Clip.Right - 1
&& Rune.ColumnWidth ((char)contents [crow, ccol, 0]) > 1) {
var prevPosition = GetOutputBufferPosition () + 1;
OutputBuffer [prevPosition].Char.UnicodeChar = (char)' ';
contents [crow, ccol + 1, 0] = (int)(uint)' ';
}
if (runeWidth > 1 && ccol == Clip.Right - 1) {
OutputBuffer [position].Char.UnicodeChar = (char)' ';
contents [crow, ccol, 0] = (int)(uint)' ';
} else {
OutputBuffer [position].Char.UnicodeChar = (char)rune;
contents [crow, ccol, 0] = (int)(uint)rune;
}
OutputBuffer [position].Attributes = (ushort)currentAttribute;
contents [crow, ccol, 1] = currentAttribute;
contents [crow, ccol, 2] = 1;
WindowsConsole.SmallRect.Update (ref damageRegion, (short)ccol, (short)crow);
}
OutputBuffer [position].Attributes = (ushort)currentAttribute;
contents [crow, ccol, 1] = currentAttribute;
contents [crow, ccol, 2] = 1;
WindowsConsole.SmallRect.Update (ref damageRegion, (short)ccol, (short)crow);
}
ccol++;
if (runeWidth < 0 || runeWidth > 0) {
ccol++;
}
if (runeWidth > 1) {
if (validClip && ccol < Clip.Right) {
position = GetOutputBufferPosition ();

View File

@@ -719,7 +719,7 @@ namespace Terminal.Gui.ViewTests {
TestHelpers.AssertDriverContentsWithFrameAre (@"
┌──────────────┐
│Les Misrables│
│Les Misérables│
◄ └───┐
│hi2 │
└──────────────────┘", output);
@@ -756,7 +756,7 @@ namespace Terminal.Gui.ViewTests {
┌──────────────────┐
│hi2 │
◄ ┌───┘
│Les Misrables│
│Les Misérables│
└──────────────┘ ", output);
}