about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/render/renderdocument.nim29
-rw-r--r--src/types/color.nim18
2 files changed, 26 insertions, 21 deletions
diff --git a/src/render/renderdocument.nim b/src/render/renderdocument.nim
index d18dbdd5..00719023 100644
--- a/src/render/renderdocument.nim
+++ b/src/render/renderdocument.nim
@@ -14,9 +14,9 @@ import types/color
 import utils/twtstr
 
 func formatFromWord(computed: ComputedFormat): Format =
-  result.fgcolor = computed.color.cellColor()
+  result.fgcolor = cellColor(computed.color)
   if computed.bgcolor.a != 0:
-    result.bgcolor = computed.bgcolor.cellColor()
+    result.bgcolor = cellColor(computed.bgcolor)
   if computed.fontstyle in { FONT_STYLE_ITALIC, FONT_STYLE_OBLIQUE }:
     result.italic = true
   if computed.fontweight > 500:
@@ -127,28 +127,25 @@ proc setText(lines: var FlexibleGrid, linestr: string, cformat: ComputedFormat,
     lnode = lines[y].formats[fi].node
     if lines[y].formats[fi].pos == x:
       # Replace.
-      if cformat.bgcolor.a == 0: #TODO alpha blending
-        # We must check if the old string's last x position is greater than
-        # the new string's first x position. If not, we cannot inherit
-        # its bgcolor (which is supposed to end before the new string started.)
-        if nx > cx:
-          format.bgcolor = lines[y].formats[fi].format.bgcolor
+      # We must check if the old string's last x position is greater than
+      # the new string's first x position. If not, we cannot inherit
+      # its bgcolor (which is supposed to end before the new string started.)
+      if nx > cx:
+        format.bgcolor = lines[y].formats[fi].format.bgcolor.blend(format.bgcolor)
       lines[y].formats.delete(fi)
       lines[y].insertFormat(x, fi, format, cformat.node)
     else:
       # First format's pos < x => split it up.
       assert lines[y].formats[fi].pos < x
-      if cformat.bgcolor.a == 0: #TODO alpha blending
-        if nx > cx: # see above
-          format.bgcolor = lines[y].formats[fi].format.bgcolor
+      if nx > cx: # see above
+        format.bgcolor = format.bgcolor.blend(lines[y].formats[fi].format.bgcolor)
       inc fi # insert after first format
       lines[y].insertFormat(x, fi, format, cformat.node)
   inc fi # skip last format
 
   while fi < lines[y].formats.len and lines[y].formats[fi].pos < nx:
     # Other formats must be > x => replace them
-    if cformat.bgcolor.a == 0: #TODO alpha blending
-      format.bgcolor = lines[y].formats[fi].format.bgcolor
+    format.bgcolor = lines[y].formats[fi].format.bgcolor
     let px = lines[y].formats[fi].pos
     lformat = lines[y].formats[fi].format # save for later use
     lnode = lines[y].formats[fi].node
@@ -200,7 +197,7 @@ proc setSpacing(lines: var FlexibleGrid, spacing: InlineSpacing, x, y: int, wind
   lines.setText(linestr, spacing.format, x, y)
 
 proc paintBackground(lines: var FlexibleGrid, color: RGBAColor, startx, starty, endx, endy: int, node: StyledNode, window: WindowAttributes) =
-  let color = color.cellColor()
+  let color = cellColor(color)
 
   var starty = starty div window.ppl
   var endy = endy div window.ppl
@@ -333,8 +330,8 @@ proc renderBlockBox(grid: var FlexibleGrid, box: BlockBox, x, y: int, window: Wi
       posy = y
 
     if box.computed{"visibility"} == VISIBILITY_VISIBLE:
-      if box.computed{"background-color"}.a != 0: #TODO color blending
-        grid.paintBackground(box.computed{"background-color"}, x, y, x + box.width, y + box.height, box.node, window)
+      grid.paintBackground(box.computed{"background-color"}, x, y,
+        x + box.width, y + box.height, box.node, window)
       if box.computed{"background-image"}.t == CONTENT_IMAGE and box.computed{"background-image"}.s != "":
         # ugly hack for background-image display... TODO actually display images
         let s = "[img]"
diff --git a/src/types/color.nim b/src/types/color.nim
index b0f3a67f..b970b25d 100644
--- a/src/types/color.nim
+++ b/src/types/color.nim
@@ -27,12 +27,18 @@ func `==`*(a, b: RGBAColor): bool {.borrow.}
 func rgbcolor*(color: CellColor): RGBColor =
   cast[RGBColor](color.n)
 
+func rgbacolor*(color: CellColor): RGBColor =
+  cast[RGBColor](color.n)
+
 func color*(color: CellColor): uint8 =
   cast[uint8](color.n)
 
 func cellColor*(rgb: RGBColor): CellColor =
   return CellColor(rgb: true, n: uint32(rgb))
 
+func cellColor*(rgba: RGBAColor): CellColor =
+  return CellColor(rgb: true, n: uint32(rgba))
+
 func cellColor*(c: uint8): CellColor =
   return CellColor(rgb: false, n: uint32(c))
 
@@ -305,6 +311,10 @@ proc straight*(c: RGBAColor): RGBAColor =
   return rgba(r, g, b, c.a)
 
 func blend*(c0, c1: RGBAColor): RGBAColor =
+  if c0.a == 0:
+    return c1
+  if c1.a == 0:
+    return c0
   let pc0 = c0.premul()
   let pc1 = c1.premul()
   let k = 255 - pc1.a
@@ -317,11 +327,9 @@ func blend*(c0, c1: RGBAColor): RGBAColor =
   let res = straight(pres)
   return res
 
-#func blend*(c0, c1: RGBAColor): RGBAColor =
-#  const norm = 1f64 / 255f64
-#  let c0a = float64(c0.a) * norm
-#  let c1a = float64(c1.a) * norm
-#  let a0 = c0a + c1a * (1 - c0a)
+# Kind of a hack, as we don't actually check if CellColor is rgbacolor.
+func blend*(c0, c1: CellColor): CellColor =
+  return cellColor(c0.rgbacolor.blend(c1.rgbacolor))
 
 func rgb*(r, g, b: uint8): RGBColor =
   return RGBColor((uint32(r) shl 16) or (uint32(g) shl 8) or uint32(b))