about summary refs log tree commit diff stats
path: root/src/render
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2022-12-10 19:05:38 +0100
committerbptato <nincsnevem662@gmail.com>2022-12-10 19:05:38 +0100
commit1e858c874804444bc4b95b6e89eb96a0deb8473c (patch)
tree3151b498e19c6d6eed3d90827483eb270314f3da /src/render
parentd963385cd9fd77f0a950c5b92be7774bbf76d661 (diff)
downloadchawan-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.nim75
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