about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2021-10-03 12:20:39 +0200
committerbptato <nincsnevem662@gmail.com>2021-10-03 12:20:39 +0200
commit71f08f380b233ad415ab6954924c395a85ffc577 (patch)
tree213d4166ac0bdae343a34bcf260d1385e2cc53e7
parent9996586865f931b6da19779520eb7671eddc6c4d (diff)
downloadchawan-71f08f380b233ad415ab6954924c395a85ffc577.tar.gz
Add RowBox structure
-rw-r--r--src/css/box.nim7
-rw-r--r--src/io/buffer.nim28
-rw-r--r--src/layout/layout.nim (renamed from src/html/renderer.nim)42
-rw-r--r--src/main.nim2
4 files changed, 60 insertions, 19 deletions
diff --git a/src/css/box.nim b/src/css/box.nim
index e0777878..457cccb0 100644
--- a/src/css/box.nim
+++ b/src/css/box.nim
@@ -18,10 +18,15 @@ type
     marginEdge*: CSSRect
     children*: seq[CSSBox]
 
+  CSSRowBox* = object
+    width*: int
+    height*: int
+    runes*: seq[Rune]
+
   CSSInlineBox* = ref CSSInlineBoxObj
   CSSInlineBoxObj = object of CSSBox
     fromx*: int
-    content*: FlexibleGrid
+    content*: seq[CSSRowBox]
 
   CSSBlockBox* = ref CSSBlockBoxObj
   CSSBlockBoxObj = object of CSSBox
diff --git a/src/io/buffer.nim b/src/io/buffer.nim
index cfea36e3..66ed6aaf 100644
--- a/src/io/buffer.nim
+++ b/src/io/buffer.nim
@@ -191,6 +191,8 @@ func cellWidthOverlap*(buffer: Buffer, x: int, y: int): int =
 func currentCellWidth*(buffer: Buffer): int = buffer.cellWidthOverlap(buffer.cursorx - buffer.fromx, buffer.cursory - buffer.fromy)
 
 func currentLineWidth*(buffer: Buffer): int =
+  if buffer.cursory > buffer.lines.len:
+    return 0
   return buffer.lines[buffer.cursory].width()
 
 func maxScreenWidth*(buffer: Buffer): int =
@@ -526,6 +528,22 @@ proc setLine*(buffer: Buffer, x: int, y: int, line: FlexibleLine) =
     buffer.lines[y].add(line[i])
     inc i
 
+proc setRowBox(buffer: Buffer, x: int, y: int, line: CSSRowBox) =
+  while buffer.lines.len <= y:
+    buffer.lines.add(newSeq[FlexibleCell]())
+
+  var i = 0
+  var cx = 0
+  while cx < x and i < buffer.lines[y].len:
+    cx += buffer.lines[y][i].rune.width()
+    inc i
+
+  buffer.lines[y].setLen(i)
+  i = 0
+  while i < line.width:
+    buffer.lines[y].add(FlexibleCell(rune: line.runes[i]))
+    inc i
+
 proc reshape*(buffer: Buffer) =
   buffer.display = newFixedGrid(buffer.width, buffer.height)
   buffer.statusmsg = newFixedGrid(buffer.width)
@@ -543,6 +561,11 @@ proc refreshDisplay*(buffer: Buffer) =
   if buffer.fromy > buffer.lastVisibleLine - 1:
     buffer.fromy = 0
     buffer.cursory = buffer.lastVisibleLine - 1
+
+  if buffer.lines.len == 0:
+    buffer.cursory = 0
+    return
+
   for line in buffer.lines[buffer.fromy..buffer.lastVisibleLine - 1]:
     var w = 0
     var i = 0
@@ -599,10 +622,13 @@ proc renderDocument*(buffer: Buffer) =
         if i == 0:
           x = inline.fromx
         var y = box.innerEdge.y1 + i
-        buffer.setLine(x, y, line)
+
+        buffer.setRowBox(x, y, line)
 
     for child in box.children:
       stack.add(child)
+  
+  eprint "lines", buffer.lines.len
 
 proc cursorBufferPos(buffer: Buffer) =
   let x = max(buffer.cursorx - buffer.fromx, 0)
diff --git a/src/html/renderer.nim b/src/layout/layout.nim
index 9e947534..043c0e08 100644
--- a/src/html/renderer.nim
+++ b/src/layout/layout.nim
@@ -8,13 +8,11 @@ import io/buffer
 import io/cell
 import utils/twtstr
 
-# basically these are the "line boxes". though honestly this is an awful
-# way to model them... but it's fine for now, I guess. TODO
-# no it's actually not fine number one priority is making it work TODO TODO TODO
-proc generateGrids(text: Text, maxwidth: int, maxheight: int, x: int, y: int, fromx: int = x): FlexibleGrid =
+proc generateGrids(text: Text, maxwidth: int, maxheight: int, x: int, y: int, fromx: int = x): seq[CSSRowBox] =
   var r: Rune
-  var rowgrid: FlexibleLine
+  var rowbox: CSSRowBox
   var i = 0
+  var whitespace = false
   if fromx > x:
     let m = fromx - x + maxwidth
     var w = 0
@@ -26,12 +24,23 @@ proc generateGrids(text: Text, maxwidth: int, maxheight: int, x: int, y: int, fr
         i = pi
         break
       else:
-        rowgrid.add(FlexibleCell(rune: r))
-        w += rw
-    result.add(rowgrid)
+        if r.isWhitespace():
+          if not whitespace:
+            whitespace = true
+            rowbox.runes.add(Rune(' '))
+            inc rowbox.width
+            w += rw
+        else:
+          if whitespace:
+            whitespace = false
+          rowbox.runes.add(r)
+          inc rowbox.width
+          w += rw
+
+    result.add(rowbox)
 
   if i < text.data.len:
-    rowgrid.setLen(0)
+    rowbox = CSSRowBox()
     var w = 0
     while i < text.data.len:
       let pi = i
@@ -40,14 +49,15 @@ proc generateGrids(text: Text, maxwidth: int, maxheight: int, x: int, y: int, fr
       if rw + w > maxwidth:
         i = pi
         w = 0
-        result.add(rowgrid)
-        rowgrid.setLen(0)
+        result.add(rowbox)
+        rowbox = CSSRowBox()
       else:
-        rowgrid.add(FlexibleCell(rune: r))
+        rowbox.runes.add(r)
+        inc rowbox.width
         w += rw
 
-  if rowgrid.len > 0:
-    result.add(rowgrid)
+  if rowbox.width > 0:
+    result.add(rowbox)
 
 proc generateBox(text: Text, maxwidth: int, maxheight: int, x: int, y: int, fromx: int): CSSInlineBox =
   new(result)
@@ -59,7 +69,7 @@ proc generateBox(text: Text, maxwidth: int, maxheight: int, x: int, y: int, from
   var width = 0
   for grid in result.content:
     inc height
-    width = max(width, grid.len)
+    width = max(width, grid.width)
   
   height = min(height, maxheight)
   width = min(width, maxwidth)
@@ -79,7 +89,7 @@ proc generateChildBoxes(elem: Element, maxwidth: int, maxheight: int, x: int, y:
         result.add(box)
         cy += box.h
         if box.content.len > 0:
-          cx = box.content[^1].width()
+          cx = box.content[^1].width
     of ELEMENT_NODE:
       let box = Element(child).generateBox(maxwidth, maxheight, x, cy, cx)
       if box != nil:
diff --git a/src/main.nim b/src/main.nim
index b1345ce2..9661ba10 100644
--- a/src/main.nim
+++ b/src/main.nim
@@ -5,7 +5,7 @@ import streams
 
 import html/parser
 import html/dom
-import html/renderer
+import layout/layout
 import io/buffer
 import io/term
 import config/config