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

Space+Underline is not rendered properly #4901

Open
ceccopierangiolieugenio opened this issue Dec 6, 2023 · 11 comments
Open

Space+Underline is not rendered properly #4901

ceccopierangiolieugenio opened this issue Dec 6, 2023 · 11 comments

Comments

@ceccopierangiolieugenio
Copy link

ceccopierangiolieugenio commented Dec 6, 2023

Details

  • Browser and browser version:
    • Firefox: 120.0
    • Vivaldi: 6.4.3160.47 (Stable channel) stable (64-bit)
    • Edge: 119.0.2151.97 (Official build) (64-bit)
  • OS version:
    • Linux: Pop!_OS 22.04 LTS
  • xterm.js version:
    • "xterm": "^5.3.0"

Steps to reproduce

follow the installation steps on the homepage: https://xtermjs.org

npm install xterm

Use this html testing file:

<!doctype html>
  <html>
    <head>
      <link rel="stylesheet" href="node_modules/xterm/css/xterm.css" />
      <script src="node_modules/xterm/lib/xterm.js"></script>
    </head>
    <body>
      <div id="terminal"></div>
      <script>
        var term = new Terminal();
        term.open(document.getElementById('terminal'));
        term.write('                      # CSI Ps m  Character Attributes (SGR).\n\r')
        term.write('Hello from \x1B[1;0;31mxterm.js   test\x1B[0m Ps=0 -> Normal (default), VT100.\n\r')
        term.write('Hello from \x1B[1;1;31mxterm.js   test\x1B[0m Ps=1 -> Bold, VT100.\n\r')
        term.write('Hello from \x1B[1;2;31mxterm.js   test\x1B[0m Ps=2 -> Faint, decreased intensity, ECMA-48 2nd.\n\r')
        term.write('Hello from \x1B[1;3;31mxterm.js   test\x1B[0m Ps=3 -> Italicized, ECMA-48 2nd.\n\r')
        term.write('Hello from \x1B[1;4;31mxterm.js   test\x1B[0m Ps=4 -> Underlined, VT100.\n\r')
        term.write('Hello from \x1B[1;5;31mxterm.js   test\x1B[0m Ps=5 -> Blink, VT100. - Bold in X11R6 xterm.\n\r')
        term.write('Hello from \x1B[1;7;31mxterm.js   test\x1B[0m Ps=7 -> Inverse, VT100.\n\r')
        term.write('Hello from \x1B[1;8;31mxterm.js   test\x1B[0m Ps=8 -> Invisible, i.e., hidden, ECMA-48 2nd, VT300.\n\r')
        term.write('Hello from \x1B[1;9;31mxterm.js   test\x1B[0m Ps=9 -> Crossed-out characters, ECMA-48 3rd.\n\r')
      </script>
    </body>
  </html>

Issue:

as shown here:
image
The fifth line should render three underlined spaces but those are not vivible

This issue is noticeable also if I use pyTermTk, where only the different chars of the buffer are sent to the terminal but the entire line is affected:
Peek 2023-12-06 15-15

Regression

  • xterm.js - 5.0.0
    No issues:
    image
  • xterm.js - 5.1.0, 5.2.0
    Some artifacts are displayed:
    image
  • xterm.js - 5.3.0
    Underlined Spaces are not rendered:
    image
@jerch
Copy link
Member

jerch commented Dec 7, 2023

@ceccopierangiolieugenio Whats the exact byte content sent for that underline line?

@ceccopierangiolieugenio
Copy link
Author

ceccopierangiolieugenio commented Dec 7, 2023

@jerch
I managed to reproduce the issue just pushing this string to the terminal as reported in the description:
'\x1B[1;4;31mxterm.js test\x1B[0m'
Is it there a way to enable some debug info to check which exact bytes are sent/received?

@jerch
Copy link
Member

jerch commented Dec 7, 2023

You can get byte content on console.log, if you enable the debug log in the terminal. I am asking for the byte content, because your screenshot for xterm.js - 5.1.0, 5.2.0 indicates some issues with encoding (looks like mixing latin-1 with utf-8). Once we have ruled that out, we can check if the renderers do crazy things.

@ceccopierangiolieugenio
Copy link
Author

New test where I used for testing:

      <div id="terminal"></div>
      <script>
        var term = new Terminal({
            logLevel: 'debug',
            allowProposedApi: true});
        term.open(document.getElementById('terminal'));
        term.write('                      # CSI Ps m  Character Attributes (SGR).\n\r')
        term.write('Hello from \x1B[1;0;31mxterm.js   test\x1B[0m Ps=0 -> Normal (default), VT100.\n\r')
        term.write('Hello from \x1B[1;1;31mxterm.js   test\x1B[0m Ps=1 -> Bold, VT100.\n\r')
        term.write('Hello from \x1B[1;3;31mxterm.js   test\x1B[0m Ps=3 -> Italicized, ECMA-48 2nd.\n\r')
        term.write('Hello from \x1B[1;4;31mxterm.js   test\x1B[0m Ps=4 -> Underlined, VT100.\n\r')
        term.write('Hello from \x1B[4;2mxterm.js   test\x1B[0m Ps=4 -> Underlined, VT100.\n\r')
        term.write('Hello from \x1B[4;5mxterm.js   test\x1B[0m Ps=4 -> Underlined, VT100.\n\r')
        term.write('Hello from \x1B[1;9;31mxterm.js   test\x1B[0m Ps=9 -> Crossed-out characters, ECMA-48 3rd.\n\r')
      </script>

Here is a comparison between the different versions, the bytes sent are identical;

xterm.js 5.0.0

image

Sent: "1 �[1;0;31mA B  C�[0mD"
[ 49, 32, 27, 91, 49, 59, 48, 59, 51, 49, 109, 65, 32, 66, 32, 32, 67, 27, 91, 48, 109, 68, 10, 13 ]
Sent: "2 �[1;1;31mA B  C�[0mD"
[ 50, 32, 27, 91, 49, 59, 49, 59, 51, 49, 109, 65, 32, 66, 32, 32, 67, 27, 91, 48, 109, 68, 10, 13 ]
Sent: "3 �[1;3;31mA B  C�[0mD" 
[ 51, 32, 27, 91, 49, 59, 51, 59, 51, 49, 109, 65, 32, 66, 32, 32, 67, 27, 91, 48, 109, 68, 10, 13 ]
Sent: "4 �[1;4;31mA B  C�[0mD" 
[ 52, 32, 27, 91, 49, 59, 52, 59, 51, 49, 109, 65, 32, 66, 32, 32, 67, 27, 91, 48, 109, 68, 10, 13 ]
Sent: "5 �[4;2mA B  C�[0mD" 
[ 53, 32, 27, 91, 52, 59, 50, 109, 65, 32, 66, 32, 32, 67, 27, 91, 48, 109, 68, 10, 13 ]
Sent: "6 �[4;5mA B  C�[0mD" 
[ 54, 32, 27, 91, 52, 59, 53, 109, 65, 32, 66, 32, 32, 67, 27, 91, 48, 109, 68, 10, 13 ]
Sent: "7 �[1;9;31mA B  C�[0mD" 
[ 55, 32, 27, 91, 49, 59, 57, 59, 51, 49, 109, 65, 32, 66, 32, 32, 67, 27, 91, 48, 109, 68, 10, 13 ]

xterm.js 5.1.0

| image | image | image |

Sent: "1 �[1;0;31mA B  C�[0mD" 
[ 49, 32, 27, 91, 49, 59, 48, 59, 51, 49, 109, 65, 32, 66, 32, 32, 67, 27, 91, 48, 109, 68, 10, 13 ]
Sent: "2 �[1;1;31mA B  C�[0mD" 
[ 50, 32, 27, 91, 49, 59, 49, 59, 51, 49, 109, 65, 32, 66, 32, 32, 67, 27, 91, 48, 109, 68, 10, 13 ]
Sent: "3 �[1;3;31mA B  C�[0mD" 
[ 51, 32, 27, 91, 49, 59, 51, 59, 51, 49, 109, 65, 32, 66, 32, 32, 67, 27, 91, 48, 109, 68, 10, 13 ]
Sent: "4 �[1;4;31mA B  C�[0mD" 
[ 52, 32, 27, 91, 49, 59, 52, 59, 51, 49, 109, 65, 32, 66, 32, 32, 67, 27, 91, 48, 109, 68, 10, 13 ]
Sent: "5 �[4;2mA B  C�[0mD" 
[ 53, 32, 27, 91, 52, 59, 50, 109, 65, 32, 66, 32, 32, 67, 27, 91, 48, 109, 68, 10, 13 ]
Sent: "6 �[4;5mA B  C�[0mD" 
[ 54, 32, 27, 91, 52, 59, 53, 109, 65, 32, 66, 32, 32, 67, 27, 91, 48, 109, 68, 10, 13 ]
Sent: "7 �[1;9;31mA B  C�[0mD" 
[ 55, 32, 27, 91, 49, 59, 57, 59, 51, 49, 109, 65, 32, 66, 32, 32, 67, 27, 91, 48, 109, 68, 10, 13 ]

xterm.js 5.3.0

| image | image |

Sent: "1 �[1;0;31mA B  C�[0mD" 
[ 49, 32, 27, 91, 49, 59, 48, 59, 51, 49, 109, 65, 32, 66, 32, 32, 67, 27, 91, 48, 109, 68, 10, 13 ]
Sent: "2 �[1;1;31mA B  C�[0mD" 
[ 50, 32, 27, 91, 49, 59, 49, 59, 51, 49, 109, 65, 32, 66, 32, 32, 67, 27, 91, 48, 109, 68, 10, 13 ]
Sent: "3 �[1;3;31mA B  C�[0mD" 
[ 51, 32, 27, 91, 49, 59, 51, 59, 51, 49, 109, 65, 32, 66, 32, 32, 67, 27, 91, 48, 109, 68, 10, 13 ]
Sent: "4 �[1;4;31mA B  C�[0mD" 
[ 52, 32, 27, 91, 49, 59, 52, 59, 51, 49, 109, 65, 32, 66, 32, 32, 67, 27, 91, 48, 109, 68, 10, 13 ]
Sent: "5 �[4;2mA B  C�[0mD" 
[ 53, 32, 27, 91, 52, 59, 50, 109, 65, 32, 66, 32, 32, 67, 27, 91, 48, 109, 68, 10, 13 ]
Sent: "6 �[4;5mA B  C�[0mD" 
[ 54, 32, 27, 91, 52, 59, 53, 109, 65, 32, 66, 32, 32, 67, 27, 91, 48, 109, 68, 10, 13 ]
Sent: "7 �[1;9;31mA B  C�[0mD" 
[ 55, 32, 27, 91, 49, 59, 57, 59, 51, 49, 109, 65, 32, 66, 32, 32, 67, 27, 91, 48, 109, 68, 10, 13 ]

@jerch
Copy link
Member

jerch commented Dec 7, 2023

Hmm where does that dotted uppercase A come from (not even sure which unicode thingy that is)? How do you send the data to the terminal? If those numbers in the array are indeed the sent bytes to the terminal, then this weird char should not have occurred at all.
Can you expose the term variable on top level and try to post here the bufferline content? You can grab it like that from the console:

<youTermVar>._core.buffer.lines.get(<lineNumber>).translateToString()

(Note that I cannot repro any of this, so there is mostly something off on your end and how you provide the data to the terminal.)

@jerch
Copy link
Member

jerch commented Dec 7, 2023

Plz also see https://stackoverflow.com/a/1462039/12548337, might explain that Å char. Maybe you forgot to declare the html document as utf-8?

@tisilent
Copy link
Contributor

tisilent commented Dec 8, 2023

@jerch I have verified. It's encoding issue, but why does the xterm demo work properly. 😟

@tisilent
Copy link
Contributor

tisilent commented Dec 8, 2023

128
😟

@ceccopierangiolieugenio
Copy link
Author

ceccopierangiolieugenio commented Dec 8, 2023

Thanks @jerch it is exactly the issue reported in:
https://stackoverflow.com/a/1462039/12548337
I fixed it adding in the header:

   <head>
      <meta charset="utf-8">
   <head>

The issue was caused by the encoding of the '\xa0' in:

if (text === ' ') {
text = '\xa0'; // = &nbsp;
}

Unfortunately I never managed to run the demo, I amnot a js/ts expert and I don'know how to build and start it.

@jerch
Copy link
Member

jerch commented Dec 8, 2023

@jerch I have verified. It's encoding issue, but why does the xterm demo work properly. 😟

The demo uses utf-8 encoding on its document. For the DOM renderer this is indeed crucial, as we forward any unicode chars directly to the DOM. With non unicode-capable encoding the DOM then would make something else out of those chars.
No clue if this has an impact on the other renderers and whether the document encoding also changes text drawing onto canvas.

@jerch
Copy link
Member

jerch commented Dec 8, 2023

@Tyriar The need for an utf-8 encoded document for the DOM renderer feels like a surprising limitation (in fact it isnt when thinking about it for a few seconds, also it is recommended as default with html5). Should we mention that in some sort of a document setup guide?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants