diff options
author | bptato <nincsnevem662@gmail.com> | 2022-12-10 19:05:38 +0100 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2022-12-10 19:05:38 +0100 |
commit | 1e858c874804444bc4b95b6e89eb96a0deb8473c (patch) | |
tree | 3151b498e19c6d6eed3d90827483eb270314f3da /src/render | |
parent | d963385cd9fd77f0a950c5b92be7774bbf76d661 (diff) | |
download | chawan-1e858c874804444bc4b95b6e89eb96a0deb8473c.tar.gz |
Add support for the encoding standard, fix parseLegacyColor
Also, fix a bug in the
Diffstat (limited to 'src/render')
-rw-r--r-- | src/render/rendertext.nim | 75 |
1 files changed, 43 insertions, 32 deletions
diff --git a/src/render/rendertext.nim b/src/render/rendertext.nim index a43a50c5..68da0557 100644 --- a/src/render/rendertext.nim +++ b/src/render/rendertext.nim @@ -1,6 +1,9 @@ import streams +import unicode import buffer/cell +import data/charset +import strings/decoderstream import utils/twtstr const tabwidth = 8 @@ -48,17 +51,18 @@ proc renderPlainText*(text: string): FlexibleGrid = type StreamRenderer* = object spaces: int - stream*: Stream ansiparser: AnsiCodeParser format: Format af: bool + decoder: DecoderStream proc newStreamRenderer*(stream: Stream): StreamRenderer = result.format = newFormat() result.ansiparser.state = PARSE_DONE - result.stream = stream + result.decoder = newDecoderStream(stream, CHARSET_UTF_8) proc renderStream*(grid: var FlexibleGrid, renderer: var StreamRenderer, len: int) = + if len == 0: return template add_format() = if renderer.af: renderer.af = false @@ -66,36 +70,43 @@ proc renderStream*(grid: var FlexibleGrid, renderer: var StreamRenderer, len: in if grid.len == 0: grid.addLine() var i = 0 - while i < len and not renderer.stream.atEnd: - let c = renderer.stream.readChar() - if renderer.ansiparser.state != PARSE_DONE: - let cancel = renderer.ansiparser.parseAnsiCode(renderer.format, c) - if not cancel: - if renderer.ansiparser.state == PARSE_DONE: - renderer.af = true - continue - case c - of '\n': - add_format - grid.addLine() - of '\r': discard - of '\t': - add_format - for i in 0 ..< tabwidth - renderer.spaces: - grid[^1].str &= ' ' - renderer.spaces = 0 - of ' ': - add_format - grid[^1].str &= c - inc renderer.spaces - if renderer.spaces == 8: - renderer.spaces = 0 - of '\e': - renderer.ansiparser.reset() - elif c in Controls: - add_format - grid[^1].str &= '^' & c.getControlLetter() + var buf = newSeq[Rune](len * 4) + let n = renderer.decoder.readData(addr buf[0], buf.len * sizeof(buf[0])) + while i < n div sizeof(buf[0]): + let r = buf[i] + if r.isAscii(): + let c = cast[char](r) + if renderer.ansiparser.state != PARSE_DONE: + let cancel = renderer.ansiparser.parseAnsiCode(renderer.format, c) + if not cancel: + if renderer.ansiparser.state == PARSE_DONE: + renderer.af = true + continue + case c + of '\n': + add_format + grid.addLine() + of '\r': discard + of '\t': + add_format + for i in 0 ..< tabwidth - renderer.spaces: + grid[^1].str &= ' ' + renderer.spaces = 0 + of ' ': + add_format + grid[^1].str &= c + inc renderer.spaces + if renderer.spaces == 8: + renderer.spaces = 0 + of '\e': + renderer.ansiparser.reset() + elif c in Controls: + add_format + grid[^1].str &= '^' & c.getControlLetter() + else: + add_format + grid[^1].str &= c else: add_format - grid[^1].str &= c + grid[^1].str &= r inc i |