about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2021-11-13 01:16:50 +0100
committerbptato <nincsnevem662@gmail.com>2021-11-13 01:16:50 +0100
commit2e408503f452f0cac8ca2a63eaf59e0bfb332f1d (patch)
tree8e97bea10fe55e5336e913713094de7593d3caaa
parent5ed6ccd8e2422c28734842488896f5cbb012916c (diff)
downloadchawan-2e408503f452f0cac8ca2a63eaf59e0bfb332f1d.tar.gz
Optimized generateFullOutput
-rw-r--r--src/css/parser.nim1
-rw-r--r--src/css/style.nim1
-rw-r--r--src/io/buffer.nim299
-rw-r--r--src/io/cell.nim8
-rw-r--r--src/layout/engine.nim18
5 files changed, 169 insertions, 158 deletions
diff --git a/src/css/parser.nim b/src/css/parser.nim
index 23f8c3fb..ec2b6591 100644
--- a/src/css/parser.nim
+++ b/src/css/parser.nim
@@ -399,7 +399,6 @@ proc consumeToken(state: var CSSTokenizerState): CSSToken =
       elif state.startsWithIdentifier():
         state.reconsume()
         result = state.consumeIdentLikeToken()
-        eprint result.value
       else:
         return CSSToken(tokenType: CSS_DELIM_TOKEN, rvalue: r)
   of Rune('.'):
diff --git a/src/css/style.nim b/src/css/style.nim
index 9f0a0c7c..9611f862 100644
--- a/src/css/style.nim
+++ b/src/css/style.nim
@@ -184,7 +184,6 @@ func cssColor*(d: CSSDeclaration): CSSColor =
         raise newException(CSSValueError, "Invalid color")
     elif d.value[0] of CSSFunction:
       let f = CSSFunction(d.value[0])
-      eprint "func", f.name
       #TODO calc etc (cssnumber function or something)
       case $f.name
       of "rgb":
diff --git a/src/io/buffer.nim b/src/io/buffer.nim
index 79f8415b..30bea7ad 100644
--- a/src/io/buffer.nim
+++ b/src/io/buffer.nim
@@ -70,40 +70,52 @@ func generateFullOutput*(buffer: Buffer): seq[string] =
   var x = 0
   var y = 0
   var s = ""
+  var formatting = newFormatting()
+
   for cell in buffer.display:
     if x >= buffer.width:
       inc y
       result.add(s)
       x = 0
       s = ""
-    s &= "\e[m"
-    if cell.fgcolor != defaultColor:
-      var color = cell.fgcolor
+
+    if formatting.bold and not cell.formatting.bold or
+        formatting.italic and not cell.formatting.italic or
+        formatting.underline and not cell.formatting.underline or
+        formatting.strike and not cell.formatting.strike or
+        formatting.overline and not cell.formatting.overline:
+      s &= "\e[m"
+      formatting = newFormatting()
+
+    if cell.formatting.fgcolor != formatting.fgcolor and cell.formatting.fgcolor != defaultColor:
+      var color = cell.formatting.fgcolor
       if color.rgb:
         let rgb = color.rgbcolor
         s &= "\e[38;2;" & $rgb.r & ";" & $rgb.g & ";" & $rgb.b & "m"
       else:
         s &= "\e[" & $color.color & "m"
 
-    if cell.bgcolor != defaultColor:
-      var color = cell.bgcolor
+    if cell.formatting.bgcolor != formatting.bgcolor and cell.formatting.bgcolor != defaultColor:
+      var color = cell.formatting.bgcolor
       if color.rgb:
         let rgb = color.rgbcolor
         s &= "\e[48;2;" & $rgb.r & ";" & $rgb.g & ";" & $rgb.b & "m"
       else:
         s &= "\e[" & $color.color & "m"
 
-    if cell.bold:
+    if not formatting.bold and cell.formatting.bold:
       s &= "\e[1m"
-    if cell.italic:
+    if not formatting.italic and cell.formatting.italic:
       s &= "\e[3m"
-    if cell.underline:
+    if not formatting.underline and cell.formatting.underline:
       s &= "\e[4m"
-    if cell.strike:
+    if not formatting.strike and cell.formatting.strike:
       s &= "\e[9m"
-    if cell.overline:
+    if not formatting.overline and cell.formatting.overline:
       s &= "\e[53m"
 
+    formatting = cell.formatting
+
     s &= $cell.runes
     inc x
 
@@ -113,83 +125,83 @@ func generateFullOutput*(buffer: Buffer): seq[string] =
 # current one. ideally we should have some mechanism in place to determine
 # where we should use this and where we should just rewrite the frame, though
 # now that I think about it rewriting every frame might be a better option
-func generateSwapOutput*(buffer: Buffer): seq[DrawInstruction] =
-  var fgcolor: CellColor
-  var bgcolor: CellColor
-  var italic = false
-  var bold = false
-  var underline = false
-
-  let max = buffer.width * buffer.height
-  let curr = buffer.display
-  let prev = buffer.prevdisplay
-  var x = 0
-  var y = 0
-  var cx = 0
-  var cy = 0
-  var i = 0
-  var text: seq[Rune]
-  while i < max:
-    if x >= buffer.width:
-      x = 0
-      cx = 0
-      text &= Rune('\n')
-      inc y
-      inc cy
-
-    if curr[i] != prev[i]:
-      let currwidth = curr[i].runes.width()
-      let prevwidth = prev[i].runes.width()
-      if (curr[i].runes.len > 0 or currwidth < prevwidth) and (x != cx or y != cy):
-        if text.len > 0:
-          result.add(DrawInstruction(t: DRAW_TEXT, text: text))
-          text.setLen(0)
-        result.add(DrawInstruction(t: DRAW_GOTO, x: x, y: y))
-        cx = x
-        cy = y
-
-      let cancont =
-        (curr[i].fgcolor == fgcolor and curr[i].bgcolor == bgcolor and
-         curr[i].italic == italic and curr[i].bold == bold and curr[i].underline == underline)
-
-      if text.len > 0 and not cancont:
-        result.add(DrawInstruction(t: DRAW_TEXT, text: text))
-        text.setLen(0)
-
-      if curr[i].fgcolor != fgcolor:
-        fgcolor = curr[i].fgcolor
-        result.add(DrawInstruction(t: DRAW_FGCOLOR, color: fgcolor))
-
-      if curr[i].bgcolor != bgcolor:
-        bgcolor = curr[i].bgcolor
-        result.add(DrawInstruction(t: DRAW_BGCOLOR, color: bgcolor))
-
-      if curr[i].italic != italic or curr[i].bold != bold or curr[i].underline != underline:
-        if italic and not curr[i].italic or bold and not curr[i].bold or underline and not curr[i].underline:
-          result.add(DrawInstruction(t: DRAW_RESET))
-          if fgcolor != defaultColor:
-            result.add(DrawInstruction(t: DRAW_FGCOLOR, color: fgcolor))
-          if bgcolor != defaultColor:
-            result.add(DrawInstruction(t: DRAW_BGCOLOR, color: bgcolor))
-        italic = curr[i].italic
-        bold = curr[i].bold
-        underline = curr[i].underline
-        result.add(DrawInstruction(t: DRAW_STYLE, italic: italic, bold: bold, underline: underline))
-
-      text &= curr[i].runes
-      if currwidth < prevwidth:
-        var j = 0
-        while j < prevwidth - currwidth:
-          text &= Rune(' ')
-          inc j
-      if text.len > 0:
-        inc cx
-
-    inc x
-    inc i
-  
-  if text.len > 0:
-    result.add(DrawInstruction(t: DRAW_TEXT, text: text))
+#func generateSwapOutput*(buffer: Buffer): seq[DrawInstruction] =
+#  var fgcolor: CellColor
+#  var bgcolor: CellColor
+#  var italic = false
+#  var bold = false
+#  var underline = false
+#
+#  let max = buffer.width * buffer.height
+#  let curr = buffer.display
+#  let prev = buffer.prevdisplay
+#  var x = 0
+#  var y = 0
+#  var cx = 0
+#  var cy = 0
+#  var i = 0
+#  var text: seq[Rune]
+#  while i < max:
+#    if x >= buffer.width:
+#      x = 0
+#      cx = 0
+#      text &= Rune('\n')
+#      inc y
+#      inc cy
+#
+#    if curr[i] != prev[i]:
+#      let currwidth = curr[i].runes.width()
+#      let prevwidth = prev[i].runes.width()
+#      if (curr[i].runes.len > 0 or currwidth < prevwidth) and (x != cx or y != cy):
+#        if text.len > 0:
+#          result.add(DrawInstruction(t: DRAW_TEXT, text: text))
+#          text.setLen(0)
+#        result.add(DrawInstruction(t: DRAW_GOTO, x: x, y: y))
+#        cx = x
+#        cy = y
+#
+#      let cancont =
+#        (curr[i].fgcolor == fgcolor and curr[i].bgcolor == bgcolor and
+#         curr[i].italic == italic and curr[i].bold == bold and curr[i].underline == underline)
+#
+#      if text.len > 0 and not cancont:
+#        result.add(DrawInstruction(t: DRAW_TEXT, text: text))
+#        text.setLen(0)
+#
+#      if curr[i].fgcolor != fgcolor:
+#        fgcolor = curr[i].fgcolor
+#        result.add(DrawInstruction(t: DRAW_FGCOLOR, color: fgcolor))
+#
+#      if curr[i].bgcolor != bgcolor:
+#        bgcolor = curr[i].bgcolor
+#        result.add(DrawInstruction(t: DRAW_BGCOLOR, color: bgcolor))
+#
+#      if curr[i].italic != italic or curr[i].bold != bold or curr[i].underline != underline:
+#        if italic and not curr[i].italic or bold and not curr[i].bold or underline and not curr[i].underline:
+#          result.add(DrawInstruction(t: DRAW_RESET))
+#          if fgcolor != defaultColor:
+#            result.add(DrawInstruction(t: DRAW_FGCOLOR, color: fgcolor))
+#          if bgcolor != defaultColor:
+#            result.add(DrawInstruction(t: DRAW_BGCOLOR, color: bgcolor))
+#        italic = curr[i].italic
+#        bold = curr[i].bold
+#        underline = curr[i].underline
+#        result.add(DrawInstruction(t: DRAW_STYLE, italic: italic, bold: bold, underline: underline))
+#
+#      text &= curr[i].runes
+#      if currwidth < prevwidth:
+#        var j = 0
+#        while j < prevwidth - currwidth:
+#          text &= Rune(' ')
+#          inc j
+#      if text.len > 0:
+#        inc cx
+#
+#    inc x
+#    inc i
+#  
+#  if text.len > 0:
+#    result.add(DrawInstruction(t: DRAW_TEXT, text: text))
 
 func generateStatusMessage*(buffer: Buffer): string =
   for cell in buffer.statusmsg:
@@ -554,17 +566,17 @@ proc setLine*(buffer: Buffer, x: int, y: int, line: FlexibleLine) =
 
 func cellFromLine(line: CSSRowBox, i: int): FlexibleCell =
   result.rune = line.runes[i]
-  result.fgcolor = line.color.cellColor()
+  result.formatting.fgcolor = line.color.cellColor()
   if line.fontstyle in { FONT_STYLE_ITALIC, FONT_STYLE_OBLIQUE }:
-    result.italic = true
+    result.formatting.italic = true
   if line.fontweight > 500:
-    result.bold = true
+    result.formatting.bold = true
   if line.textdecoration == TEXT_DECORATION_UNDERLINE:
-    result.underline = true
+    result.formatting.underline = true
   if line.textdecoration == TEXT_DECORATION_OVERLINE:
-    result.overline = true
+    result.formatting.overline = true
   if line.textdecoration == TEXT_DECORATION_LINE_THROUGH:
-    result.strike = true
+    result.formatting.strike = true
 
 proc setRowBox(buffer: Buffer, line: CSSRowBox) =
   let x = line.x
@@ -643,13 +655,7 @@ proc refreshDisplay*(buffer: Buffer) =
       if line[i].rune.width() == 0 and j != 0:
         inc n
       buffer.display[dls + j - n].runes.add(line[i].rune)
-      buffer.display[dls + j - n].fgcolor = line[i].fgcolor
-      buffer.display[dls + j - n].bgcolor = line[i].bgcolor
-      buffer.display[dls + j - n].italic = line[i].italic
-      buffer.display[dls + j - n].bold = line[i].bold
-      buffer.display[dls + j - n].underline = line[i].underline
-      buffer.display[dls + j - n].strike = line[i].strike
-      buffer.display[dls + j - n].overline = line[i].overline
+      buffer.display[dls + j - n].formatting = line[i].formatting
       j += line[i].rune.width()
       inc i
 
@@ -687,12 +693,13 @@ proc renderDocument*(buffer: Buffer) =
     let box = stack.pop()
     if box of CSSInlineBox:
       let inline = CSSInlineBox(box)
-      eprint "NEW BOX", inline.context.conty
+      #eprint "NEW BOX", inline.context.conty
       for line in inline.content:
-        eprint line
+        #eprint line
         buffer.setRowBox(line)
     else:
-      eprint "BLOCK h", box.height
+      discard
+      #eprint "BLOCK h", box.height
 
     var i = box.children.len - 1
     while i >= 0:
@@ -730,49 +737,49 @@ proc statusMsgForBuffer(buffer: Buffer) =
     msg &= " " & buffer.hovertext
   buffer.setStatusMessage(msg)
 
-proc displayBufferSwapOutput(buffer: Buffer) =
-  termGoto(0, 0)
-  let instructions = buffer.generateSwapOutput()
-  for inst in instructions:
-    case inst.t
-    of DRAW_TEXT:
-      print(inst.text)
-    of DRAW_GOTO:
-      termGoto(inst.x, inst.y)
-    of DRAW_FGCOLOR:
-      let color = inst.color
-      if inst.color.rgb:
-        let rgb = color.rgbcolor
-        print("\e[38;2;" & $rgb.r & ";" & $rgb.g & ";" & $rgb.b & "m")
-      else:
-        print("\e[" & $color.color & "m")
-    of DRAW_BGCOLOR:
-      let color = inst.color
-      if inst.color.rgb:
-        let rgb = color.rgbcolor
-        print("\e[48;2;" & $rgb.r & ";" & $rgb.g & ";" & $rgb.b & "m")
-      else:
-        print("\e[" & $color.color & "m")
-    of DRAW_STYLE:
-      var os = "\e["
-      var p = false
-      if inst.italic:
-        os &= "3"
-        p = true
-      if inst.bold:
-        if p:
-          os &= ";"
-        os &= "1"
-        p = true
-      if inst.underline:
-        if p:
-          os &= ";"
-        os &= "4"
-        p = true
-      os &= "m"
-      print(os)
-    of DRAW_RESET:
-      print("\e[0m")
+#proc displayBufferSwapOutput(buffer: Buffer) =
+#  termGoto(0, 0)
+#  let instructions = buffer.generateSwapOutput()
+#  for inst in instructions:
+#    case inst.t
+#    of DRAW_TEXT:
+#      print(inst.text)
+#    of DRAW_GOTO:
+#      termGoto(inst.x, inst.y)
+#    of DRAW_FGCOLOR:
+#      let color = inst.color
+#      if inst.color.rgb:
+#        let rgb = color.rgbcolor
+#        print("\e[38;2;" & $rgb.r & ";" & $rgb.g & ";" & $rgb.b & "m")
+#      else:
+#        print("\e[" & $color.color & "m")
+#    of DRAW_BGCOLOR:
+#      let color = inst.color
+#      if inst.color.rgb:
+#        let rgb = color.rgbcolor
+#        print("\e[48;2;" & $rgb.r & ";" & $rgb.g & ";" & $rgb.b & "m")
+#      else:
+#        print("\e[" & $color.color & "m")
+#    of DRAW_STYLE:
+#      var os = "\e["
+#      var p = false
+#      if inst.italic:
+#        os &= "3"
+#        p = true
+#      if inst.bold:
+#        if p:
+#          os &= ";"
+#        os &= "1"
+#        p = true
+#      if inst.underline:
+#        if p:
+#          os &= ";"
+#        os &= "4"
+#        p = true
+#      os &= "m"
+#      print(os)
+#    of DRAW_RESET:
+#      print("\e[0m")
 
 proc displayBuffer(buffer: Buffer) =
   termGoto(0, 0)
diff --git a/src/io/cell.nim b/src/io/cell.nim
index 50094e88..983c5b4d 100644
--- a/src/io/cell.nim
+++ b/src/io/cell.nim
@@ -4,7 +4,7 @@ import types/color
 import utils/twtstr
 
 type
-  Cell* = object of RootObj
+  Formatting* = object
     fgcolor*: CellColor
     bgcolor*: CellColor
     italic*: bool
@@ -13,6 +13,9 @@ type
     strike*: bool
     overline*: bool
 
+  Cell* = object of RootObj
+    formatting*: Formatting
+
   FlexibleCell* = object of Cell
     rune*: Rune
 
@@ -43,3 +46,6 @@ func newFixedGrid*(w: int, h: int = 1): FixedGrid =
 func width*(line: FlexibleLine): int =
   for c in line:
     result += c.rune.width()
+
+func newFormatting*(): Formatting =
+  return Formatting(fgcolor: defaultColor, bgcolor: defaultColor)
diff --git a/src/layout/engine.nim b/src/layout/engine.nim
index a8519c3f..55c8be00 100644
--- a/src/layout/engine.nim
+++ b/src/layout/engine.nim
@@ -18,19 +18,19 @@ func newBlockBox*(parent: CSSBox, vals: CSSComputedValues): CSSBlockBox =
   result.x = parent.x
   if parent.context.conty:
     inc parent.height
-    eprint "inc n"
+    #eprint "inc n"
     inc parent.context.fromy
     parent.context.conty = false
   result.y = parent.context.fromy
   let mtop = vals[PROPERTY_MARGIN_TOP].length.cells()
   if mtop > parent.bcontext.marginy:
     result.y += mtop - parent.bcontext.marginy
-    eprint "my", mtop, parent.bcontext.marginy
+    #eprint "my", mtop, parent.bcontext.marginy
     parent.bcontext.marginy = mtop
 
   result.width = parent.width
   result.context = newContext(parent)
-  eprint "inc to", result.y
+  #eprint "inc to", result.y
   result.context.fromy = result.y
   result.cssvalues = vals
 
@@ -116,7 +116,7 @@ proc processInlineBox(parent: CSSBox, str: string): CSSBox =
     ibox.context.conty = true
 
   ibox.height += rowi
-  eprint "inc i", rowi, rowbox.runes
+  #eprint "inc i", rowi, rowbox.runes
   if rowi > 0 or rowbox.width > 0:
     parent.bcontext.marginy = 0
   ibox.context.fromy += rowi
@@ -127,7 +127,7 @@ proc processInlineBox(parent: CSSBox, str: string): CSSBox =
 proc processElemBox(parent: CSSBox, elem: Element): CSSBox =
   case elem.cssvalues[PROPERTY_DISPLAY].display
   of DISPLAY_BLOCK:
-    eprint "START", elem.tagType
+    #eprint "START", elem.tagType
     result = newBlockBox(parent, elem.cssvalues)
     CSSBlockBox(result).tag = $elem.tagType
   of DISPLAY_INLINE:
@@ -145,16 +145,16 @@ proc add(parent: var CSSBox, box: CSSBox) =
     parent.context.whitespace = true
     if box.context.conty:
       inc box.height
-      eprint "inc a"
+      #eprint "inc a"
       inc box.context.fromy
       box.context.conty = false
     let mbot = box.cssvalues[PROPERTY_MARGIN_BOTTOM].length.cells()
-    eprint "inc b", mbot
+    #eprint "inc b", mbot
     box.context.fromy += mbot
     box.bcontext.marginy = mbot
-    eprint "END", CSSBlockBox(box).tag
+    #eprint "END", CSSBlockBox(box).tag
   parent.height += box.height
-  eprint "parent to", box.context.fromy
+  #eprint "parent to", box.context.fromy
   parent.context.fromy = box.context.fromy
   parent.children.add(box)