about summary refs log tree commit diff stats
path: root/src/render/renderdocument.nim
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2021-12-23 15:17:37 +0100
committerbptato <nincsnevem662@gmail.com>2021-12-23 15:19:33 +0100
commiteb16da9fdff2d483c9143a4caea641e021a9e3af (patch)
treee96d0da20325788a53e61f3b4578ee26452efd38 /src/render/renderdocument.nim
parent7c5241b8dc4c59e602976a80740281b5673ac65e (diff)
downloadchawan-eb16da9fdff2d483c9143a4caea641e021a9e3af.tar.gz
Refactor buffer rendering procedures
Diffstat (limited to 'src/render/renderdocument.nim')
-rw-r--r--src/render/renderdocument.nim87
1 files changed, 87 insertions, 0 deletions
diff --git a/src/render/renderdocument.nim b/src/render/renderdocument.nim
new file mode 100644
index 00000000..c3ad6cfe
--- /dev/null
+++ b/src/render/renderdocument.nim
@@ -0,0 +1,87 @@
+import strutils
+import unicode
+
+import css/cascade
+import css/sheet
+import css/values
+import html/dom
+import io/cell
+import io/term
+import layout/box
+import layout/engine
+import utils/twtstr
+
+func formatFromLine(line: CSSRowBox): Formatting =
+  result.fgcolor = line.color.cellColor()
+  if line.fontstyle in { FONT_STYLE_ITALIC, FONT_STYLE_OBLIQUE }:
+    result.italic_on
+  if line.fontweight > 500:
+    result.bold_on
+  if line.textdecoration == TEXT_DECORATION_UNDERLINE:
+    result.underline_on
+  if line.textdecoration == TEXT_DECORATION_OVERLINE:
+    result.overline_on
+  if line.textdecoration == TEXT_DECORATION_LINE_THROUGH:
+    result.strike_on
+
+proc setRowBox(lines: var FlexibleGrid, line: CSSRowBox) =
+  var r: Rune
+
+  var x = line.x
+  var i = 0
+  while x < 0:
+    fastRuneAt(line.str, i, r)
+    x += r.width()
+  let linestr = line.str.substr(i)
+  i = 0
+
+  let y = line.y
+
+  while lines.len <= y:
+    lines.addLine()
+
+  var cx = 0
+  while cx < x and i < lines[y].str.len:
+    fastRuneAt(lines[y].str, i, r)
+    cx += r.width()
+
+  let ostr = lines[y].str.substr(i)
+  let oformats = lines[y].formats.subformats(i)
+  lines[y].setLen(i)
+
+  lines.addFormat(y, i, line.formatFromLine(), line.nodes)
+
+  var nx = cx
+  if nx < x:
+    lines[y].str &= ' '.repeat(x - nx)
+    nx = x
+
+  lines[y].str &= linestr
+  nx += linestr.width()
+
+  i = 0
+  while cx < nx and i < ostr.len:
+    fastRuneAt(ostr, i, r)
+    cx += r.width()
+
+  if i < ostr.len:
+    let oline = FlexibleLine(str: ostr.substr(i), formats: oformats.subformats(i))
+    lines[y].add(oline)
+
+const css = staticRead"res/ua.css"
+let uastyle = css.parseStylesheet()
+proc renderDocument*(document: Document, attrs: TermAttributes, userstyle: CSSStylesheet): FlexibleGrid =
+  document.applyStylesheets(uastyle, userstyle)
+  let rootbox = document.alignBoxes(attrs)
+  var stack: seq[CSSBox]
+  stack.add(rootbox)
+  while stack.len > 0:
+    let box = stack.pop()
+    if box of CSSBlockBox:
+      for line in box.icontext.rows:
+        result.setRowBox(line)
+
+    var i = box.children.len - 1
+    while i >= 0:
+      stack.add(box.children[i])
+      dec i