diff options
author | bptato <nincsnevem662@gmail.com> | 2022-02-15 10:38:27 +0100 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2022-02-15 10:38:27 +0100 |
commit | c2236634bcbde5576949bcad7bd7ca6e9ccf3eb7 (patch) | |
tree | 0a9f4809e6d8e64f9e901dae86b2c1e2d2279a3c | |
parent | 5098a7a162a4cd7a33ed724d9266ed850013e155 (diff) | |
download | chawan-c2236634bcbde5576949bcad7bd7ca6e9ccf3eb7.tar.gz |
Fix format background unicode problems
-rw-r--r-- | src/io/cell.nim | 6 | ||||
-rw-r--r-- | src/render/renderdocument.nim | 73 |
2 files changed, 54 insertions, 25 deletions
diff --git a/src/io/cell.nim b/src/io/cell.nim index b08d11e6..af142967 100644 --- a/src/io/cell.nim +++ b/src/io/cell.nim @@ -146,12 +146,6 @@ proc addFormat*(grid: var FlexibleGrid, y, pos: int, format: Format, computed: C if computed == nil or grid[y].formats.len == 0 or grid[y].formats[^1].computed != computed: grid[y].formats.add(FormatCell(format: format, node: node, computed: computed, pos: pos)) -proc addCell*(grid: var FlexibleGrid, y: int, r: Rune) = - grid[y].str &= $r - -proc addCell*(grid: var FlexibleGrid, r: Rune) = - grid.addCell(grid.len - 1, r) - template inc_check(i: int) = inc i if i >= buf.len: diff --git a/src/render/renderdocument.nim b/src/render/renderdocument.nim index 4a012f71..f2b8d9f8 100644 --- a/src/render/renderdocument.nim +++ b/src/render/renderdocument.nim @@ -27,28 +27,62 @@ func formatFromWord(computed: ComputedFormat): Format = if computed.textdecoration == TEXT_DECORATION_BLINK: result.blink = true -#TODO: this fails to set background colors on non-ascii text correctly. -# Either figure out a workaround or change format.pos to signify width instead. -proc setFormats(lines: var FlexibleGrid, y: int, newformat: Format, oformats: seq[FormatCell], i, len, olen: int) {.inline.} = +proc setFormats(lines: var FlexibleGrid, y, ox, i: int, nx, cx: var int, + newformat: Format, oformats: seq[FormatCell], + str, ostr: string, computed: ComputedFormat = nil) {.inline.} = let obg = newformat.bgcolor + let newstrwidth = str.width() var newformat = newformat - var fpos = i + var osi = 0 + var nsi = 0 for format in oformats: - if format.pos >= i + len: - break + assert i + ostr.len > format.pos + # move cx to format.pos + while i + osi < format.pos: + var r: Rune + fastRuneAt(ostr, osi, r) + cx += r.width() + + if cx > newstrwidth + ox: + # last oformat starts after newformat ends + nx = ox + newstrwidth + return + + # move nx to cx + while nsi < str.len and nx < cx: + var r: Rune + fastRuneAt(str, nsi, r) + nx += r.width() + if format.format.bgcolor != newformat.bgcolor: newformat.bgcolor = format.format.bgcolor - lines.addFormat(y, fpos, newformat) - fpos = format.pos + if computed == nil: + lines.addFormat(y, i + nsi, newformat) + else: + # have to pass nil to force new format... TODO? + lines.addFormat(y, i + nsi, newformat, nil, computed.node) - if fpos < i + len: - newformat.bgcolor = obg - lines.addFormat(y, fpos, newformat) + # last oformat starts before newformat ends + + # move cx to last old char + while osi < ostr.len: + var r: Rune + fastRuneAt(ostr, osi, r) + cx += r.width() - if fpos != i + olen: - fpos = i + olen - if fpos < i + len: - lines.addFormat(y, i + olen, newformat) + # move nx to cx + while nsi < str.len and nx < cx: + var r: Rune + fastRuneAt(str, nsi, r) + nx += r.width() + + if nsi < str.len: + newformat.bgcolor = obg + if computed == nil: + lines.addFormat(y, i + nsi, newformat) + else: + lines.addFormat(y, i + nsi, newformat, computed, computed.node) + nx = ox + newstrwidth proc setText(lines: var FlexibleGrid, linestr: string, format: ComputedFormat, x, y: int) {.inline.} = var r: Rune @@ -69,23 +103,24 @@ proc setText(lines: var FlexibleGrid, linestr: string, format: ComputedFormat, x lines[y].setLen(i) var nx = cx + let ox = cx if nx < x: let spacelength = x - nx var spaceformat = newFormat() let str = ' '.repeat(spacelength) - lines.setFormats(y, spaceformat, oformats, i, str.len, ostr.len) + lines.setFormats(y, ox, i, nx, cx, spaceformat, oformats, str, ostr) lines[y].str &= str i += spacelength - nx = x + assert nx == x var wordformat = format.formatFromWord() - lines.setFormats(y, wordformat, oformats, i, linestr.len, ostr.len) + lines.setFormats(y, x, i, nx, cx, wordformat, oformats, linestr, ostr, format) lines[y].str &= linestr - nx += linestr.width() i = 0 + cx = ox while cx < nx and i < ostr.len: fastRuneAt(ostr, i, r) cx += r.width() |