gizak / termui

Golang terminal dashboard
MIT License
13.16k stars 787 forks source link

Chinese text in paragraph make an 'index out of range' exception and display weird. #226

Closed anson0370 closed 5 years ago

anson0370 commented 5 years ago

The official example _example/paragraph.go can reproduce this issue. Run this example can cause an 'index out of range'.

I did some debug and figured out the problem:

func TrimCells(cells []Cell, w int) []Cell {
    s := CellsToString(cells)
    s = TrimString(s, w)
    newCells := []Cell{}
    for i, r := range s { // index i will be 0, 3, 9... when range at a Chinese string
        newCells = append(newCells, Cell{r, cells[i].Style}) // then index out of range here
    }
    return newCells
}

So I fixed it like this:

func TrimCells(cells []Cell, w int) []Cell {
    s := CellsToString(cells)
    s = TrimString(s, w)
    runes := []rune(s)
    newCells := []Cell{}
    for i, r := range runes {
        newCells = append(newCells, Cell{r, cells[i].Style})
    }
    return newCells
}

No more exceptions but the display was still weird. The string "你好,世界。" would display like "你,世". I did more debug and caught the issue again:

diff --git a/widgets/paragraph.go b/widgets/paragraph.go
index 9498f16..4676897 100644
--- a/widgets/paragraph.go
+++ b/widgets/paragraph.go
@@ -8,6 +8,7 @@ import (
        "image"

        . "github.com/gizak/termui"
+       rw "github.com/mattn/go-runewidth"
 )

 type Paragraph struct {
@@ -40,8 +41,10 @@ func (self *Paragraph) Draw(buf *Buffer) {
                        break
                }
                row = TrimCells(row, self.Inner.Dx())
-               for x, cell := range row {
+               x := 0
+               for _, cell := range row {
                        buf.SetCell(cell, image.Pt(x, y).Add(self.Inner.Min))
+                       x += rw.RuneWidth(cell.Rune)
                }
        }
 }

But there are many other code like above at other widgets like list, table, etc... And looks like you are working on refactor this lib. So I didn't make a PR for it.

Thx. And sorry for my english. 😄

cjbassi commented 5 years ago

Hi thanks for pointing this out. Most of the widgets were just rewritten and it seems that support for chinese characters was overlooked. The widgets should be stable enough now that PRs are very much welcome though!

snipem commented 5 years ago

It also affected German Umlauts and possible other Unicode characters. Now it's fixed.