Bläddra i källkod

Merge pull request #669 from tig/non_printable

Addresses non-printable chars in Drivers
Charlie Kindel 5 år sedan
förälder
incheckning
1f4b9289b1

+ 2 - 2
Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs

@@ -39,14 +39,14 @@ namespace Terminal.Gui {
 		}
 
 		static bool sync = false;
-		public override void AddRune (Rune rune)
+		public override void AddRune (Rune rune) 
 		{
 			if (Clip.Contains (ccol, crow)) {
 				if (needMove) {
 					Curses.move (crow, ccol);
 					needMove = false;
 				}
-				Curses.addch ((int)(uint)rune);
+				Curses.addch ((int)(uint)MakePrintable(rune));
 			} else
 				needMove = true;
 			if (sync)

+ 1 - 0
Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs

@@ -90,6 +90,7 @@ namespace Terminal.Gui {
 		/// <param name="rune"></param>
 		public override void AddRune (Rune rune)
 		{
+			rune = MakePrintable (rune);
 			if (Clip.Contains (ccol, crow)) {
 				if (needMove) {
 					//MockConsole.CursorLeft = ccol;

+ 1 - 0
Terminal.Gui/ConsoleDrivers/NetDriver.cs

@@ -70,6 +70,7 @@ namespace Terminal.Gui {
 
 		public override void AddRune (Rune rune)
 		{
+			rune = MakePrintable (rune);
 			if (Clip.Contains (ccol, crow)) {
 				if (needMove) {
 					//Console.CursorLeft = ccol;

+ 1 - 0
Terminal.Gui/ConsoleDrivers/WindowsDriver.cs

@@ -1182,6 +1182,7 @@ namespace Terminal.Gui {
 
 		public override void AddRune (Rune rune)
 		{
+			rune = MakePrintable (rune);
 			var position = crow * Cols + ccol;
 
 			if (Clip.Contains (ccol, crow)) {

+ 23 - 1
Terminal.Gui/Core/ConsoleDriver.cs

@@ -1,4 +1,4 @@
-//
+//
 // ConsoleDriver.cs: Definition for the Console Driver API
 //
 // Authors:
@@ -558,6 +558,28 @@ namespace Terminal.Gui {
 		/// <param name="rune">Rune to add.</param>
 		public abstract void AddRune (Rune rune);
 		/// <summary>
+		/// Ensures a Rune is not a control character and can be displayed by translating characters below 0x20
+		/// to equivalent, printable, Unicode chars.
+		/// </summary>
+		/// <param name="c">Rune to translate</param>
+		/// <returns></returns>
+		public static Rune MakePrintable (Rune c)
+		{
+			if (c <= 0x1F) {
+				// ASCII (C0) control characters. 
+				return new Rune (c + 0x2400);
+			} else if (c >= 0x80 && c <= 0x9F) {
+				// C1 control characters (https://www.aivosto.com/articles/control-characters.html#c1)
+				return new Rune (0x25a1); // U+25A1, WHITE SQUARE, □: 
+			} else if (Rune.ColumnWidth (c) > 1) {
+				// BUGBUG: Until we figure out how to fix #41. Note this still doesn't help when 
+				// an Emoji or other char doesn't represent it's width correctly
+				return new Rune (0x25a1); // U+25A1, WHITE SQUARE, □: 
+			} else {
+				return c;
+			}
+		}
+		/// <summary>
 		/// Adds the specified
 		/// </summary>
 		/// <param name="str">String.</param>

+ 0 - 8
Terminal.Gui/Views/Button.cs

@@ -174,14 +174,6 @@ namespace Terminal.Gui {
 			else
 				shown_text = ustring.Make (_leftBracket) + " " + text + " " + ustring.Make (_rightBracket);
 
-			shown_text = shown_text
-				.Replace ("\f", "\u21a1")		// U+21A1 ↡ DOWNWARDS TWO HEADED ARROW
-				.Replace ("\n", "\u240a")		// U+240A (SYMBOL FOR LINE FEED, ␊)
-				.Replace ("\r", "\u240d")		// U+240D (SYMBOL FOR CARRIAGE RETURN, ␍)
-				.Replace ("\t", "\u2409")		// U+2409 ␉ SYMBOL FOR HORIZONTAL TABULATION
-				.Replace ("\v", "\u240b")		// U+240B ␋ SYMBOL FOR VERTICAL TABULATION
-				.TrimSpace ();
-
 			shown_text = GetTextFromHotKey (shown_text, '_', out hot_pos, out hot_key);
 
 			SetNeedsDisplay ();

+ 19 - 3
UICatalog/Scenarios/CharacterMap.cs

@@ -3,6 +3,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using Terminal.Gui;
+using Rune = System.Rune;
 
 namespace UICatalog {
 	/// <summary>
@@ -36,6 +37,9 @@ namespace UICatalog {
 			}
 
 			var radioItems = new (ustring radioLabel, int start, int end) [] {
+				CreateRadio("ASCII Control Characterss", 0x00, 0x1F),
+				CreateRadio("C0 Control Characters", 0x80, 0x9f),
+				CreateRadio("Hangul Jamo", 0x1100, 0x11ff),	// This is where wide chars tend to start
 				CreateRadio("Currency Symbols", 0x20A0, 0x20CF),
 				CreateRadio("Letterlike Symbols", 0x2100, 0x214F),
 				CreateRadio("Arrows", 0x2190, 0x21ff),
@@ -57,7 +61,7 @@ namespace UICatalog {
 			jumpList.Y = Pos.Bottom (label);
 			jumpList.Width = Dim.Fill ();
 			jumpList.SelectedItemChanged = (args) => {
-				charMap.Start = radioItems[args.SelectedItem].start;
+				charMap.Start = radioItems [args.SelectedItem].start;
 			};
 
 			Win.Add (jumpList);
@@ -105,6 +109,15 @@ namespace UICatalog {
 #if true
 		private void CharMap_DrawContent (Rect viewport)
 		{
+			//Rune ReplaceNonPrintables (Rune c)
+			//{
+			//	if (c < 0x20) {
+			//		return new Rune (c + 0x2400);         // U+25A1 □ WHITE SQUARE
+			//	} else {
+			//		return c;
+			//	}
+			//}
+
 			for (int header = 0; header < 16; header++) {
 				Move (viewport.X + RowHeaderWidth + (header * 2), 0);
 				Driver.AddStr ($" {header:x} ");
@@ -115,9 +128,12 @@ namespace UICatalog {
 					var rowLabel = $"U+{val / 16:x4}x";
 					Move (0, y + 1);
 					Driver.AddStr (rowLabel);
+					var prevColWasWide = false;
 					for (int col = 0; col < 16; col++) {
-						Move (viewport.X + RowHeaderWidth + (col * 2), 0 + y + 1);
-						Driver.AddStr ($" {(char)((-viewport.Y + row) * 16 + col)}");
+						var rune = new Rune ((uint)((uint)(-viewport.Y + row) * 16 + col));
+						Move (viewport.X + RowHeaderWidth + (col * 2) + (prevColWasWide ? 0 : 1), 0 + y + 1);
+						Driver.AddRune (rune);
+						//prevColWasWide = Rune.ColumnWidth(rune) > 1;
 					}
 				}
 			}