about summary refs log tree commit diff stats
path: root/src/local
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2024-09-01 01:03:50 +0200
committerbptato <nincsnevem662@gmail.com>2024-09-01 01:46:38 +0200
commit55cfd29e961488a8c1ed9eb7801d237d27bc86c7 (patch)
treec74569e15ca72d777eadcfd19a0203cbb76c3e3f /src/local
parente9466c4c436f964b53034e28356aa3f5c957a068 (diff)
downloadchawan-55cfd29e961488a8c1ed9eb7801d237d27bc86c7.tar.gz
canvas: move to separate CGI script
* stream: and passFd is now client-based, and accessible for buffers
* Bitmap's width & height is now int, not uint64
* no more non-network Bitmap special case in the pager for canvas

I just shoehorned it into the static image model, so it still doesn't
render changes after page load. But at least now it doesn't crash the
browser.
Diffstat (limited to 'src/local')
-rw-r--r--src/local/container.nim2
-rw-r--r--src/local/pager.nim55
-rw-r--r--src/local/term.nim42
3 files changed, 46 insertions, 53 deletions
diff --git a/src/local/container.nim b/src/local/container.nim
index ebfc3940..2c12c4ae 100644
--- a/src/local/container.nim
+++ b/src/local/container.nim
@@ -2070,7 +2070,7 @@ proc highlightMarks*(container: Container; display: var FixedGrid;
 
 func findCachedImage*(container: Container; image: PosBitmap;
     offx, erry, dispw: int): CachedImage =
-  let imageId = NetworkBitmap(image.bmp).imageId
+  let imageId = image.bmp.imageId
   for it in container.cachedImages:
     if it.bmp.imageId == imageId and it.width == image.width and
         it.height == image.height and it.offx == offx and it.erry == erry and
diff --git a/src/local/pager.nim b/src/local/pager.nim
index 8abaf16f..cb3f751e 100644
--- a/src/local/pager.nim
+++ b/src/local/pager.nim
@@ -130,7 +130,6 @@ type
     forkserver*: ForkServer
     formRequestMap*: Table[string, FormRequestType]
     hasload*: bool # has a page been successfully loaded since startup?
-    imageId: int # hack to allocate a new ID for canvas each frame, TODO remove
     inputBuffer*: string # currently uninterpreted characters
     iregex: Result[Regex, string]
     isearchpromise: EmptyPromise
@@ -484,8 +483,7 @@ proc redraw(pager: Pager) {.jsfunc.} =
 
 proc loadCachedImage(pager: Pager; container: Container; image: PosBitmap;
     offx, erry, dispw: int) =
-  let bmp = NetworkBitmap()
-  bmp[] = NetworkBitmap(image.bmp)[]
+  let bmp = image.bmp
   let request = newRequest(newURL("cache:" & $bmp.cacheId).get)
   let cachedImage = CachedImage(
     bmp: bmp,
@@ -505,7 +503,7 @@ proc loadCachedImage(pager: Pager; container: Container; image: PosBitmap;
       return
     let response = res.get
     let headers = newHeaders()
-    if uint64(image.width) != bmp.width or uint64(image.height) != bmp.height:
+    if image.width != bmp.width or image.height != bmp.height:
       headers.add("Cha-Image-Target-Dimensions", $image.width & 'x' &
         $image.height)
     let request = newRequest(
@@ -524,9 +522,6 @@ proc loadCachedImage(pager: Pager; container: Container; image: PosBitmap;
       pager.loader.removeCachedItem(bmp.cacheId)
       return
     let response = res.get
-    # take target sizes
-    bmp.width = uint64(image.width)
-    bmp.height = uint64(image.height)
     let headers = newHeaders({
       "Cha-Image-Dimensions": $image.width & 'x' & $image.height
     })
@@ -571,36 +566,28 @@ proc loadCachedImage(pager: Pager; container: Container; image: PosBitmap;
 proc initImages(pager: Pager; container: Container) =
   var newImages: seq[CanvasImage] = @[]
   for image in container.images:
-    var imageId = -1
-    var data: Blob = nil
-    var bmp0 = image.bmp
     var erry = 0
     var offx = 0
     var dispw = 0
-    if image.bmp of NetworkBitmap:
-      let bmp = NetworkBitmap(image.bmp)
-      if pager.term.imageMode == imSixel:
-        let xpx = (image.x - container.fromx) * pager.attrs.ppc
-        offx = -min(xpx, 0)
-        let maxwpx = pager.bufWidth * pager.attrs.ppc
-        dispw = min(int(image.width) + xpx, maxwpx) - xpx
-        let ypx = (image.y - container.fromy) * pager.attrs.ppl
-        erry = -min(ypx, 0) mod 6
-      let cached = container.findCachedImage(image, offx, erry, dispw)
-      imageId = bmp.imageId
-      if cached == nil:
-        pager.loadCachedImage(container, image, offx, erry, dispw)
-        continue
-      bmp0 = cached.bmp
-      data = cached.data
-      if not cached.loaded:
-        continue # loading
-    else:
-      imageId = pager.imageId
-      inc pager.imageId
-    let canvasImage = pager.term.loadImage(bmp0, data, container.process,
+    if pager.term.imageMode == imSixel:
+      let xpx = (image.x - container.fromx) * pager.attrs.ppc
+      offx = -min(xpx, 0)
+      let maxwpx = pager.bufWidth * pager.attrs.ppc
+      #TODO this is wrong if term caps sixel width
+      dispw = min(int(image.width) + xpx, maxwpx) - xpx
+      let ypx = (image.y - container.fromy) * pager.attrs.ppl
+      erry = -min(ypx, 0) mod 6
+    let cached = container.findCachedImage(image, offx, erry, dispw)
+    let imageId = image.bmp.imageId
+    if cached == nil:
+      pager.loadCachedImage(container, image, offx, erry, dispw)
+      continue
+    if not cached.loaded:
+      continue # loading
+    let canvasImage = pager.term.loadImage(cached.data, container.process,
       imageId, image.x - container.fromx, image.y - container.fromy,
-      image.x, image.y, pager.bufWidth, pager.bufHeight, erry, offx, dispw)
+      image.width, image.height, image.x, image.y, pager.bufWidth,
+      pager.bufHeight, erry, offx, dispw)
     if canvasImage != nil:
       newImages.add(canvasImage)
   pager.term.clearImages(pager.bufHeight)
@@ -1165,7 +1152,7 @@ proc applySiteconf(pager: Pager; url: var URL; charsetOverride: Charset;
     proxy: pager.config.network.proxy,
     filter: newURLFilter(
       scheme = some(url.scheme),
-      allowschemes = @["data", "cache"],
+      allowschemes = @["data", "cache", "stream"],
       default = true
     ),
     insecureSSLNoVerify: false
diff --git a/src/local/term.nim b/src/local/term.nim
index 78c50efc..7cd43e02 100644
--- a/src/local/term.nim
+++ b/src/local/term.nim
@@ -11,7 +11,6 @@ import chagashi/charset
 import chagashi/decoder
 import chagashi/encoder
 import config/config
-import img/bitmap
 import io/dynstream
 import js/base64
 import types/blob
@@ -57,17 +56,24 @@ type
   CanvasImage* = ref object
     pid: int
     imageId: int
+    # relative position on screen
     x: int
     y: int
+    # original dimensions (after resizing)
+    width: int
+    height: int
+    # offset (crop start)
     offx: int
     offy: int
+    # size cap (crop end)
+    # Note: this 0-based, so the final display size is
+    # (dispw - offx, disph - offy)
     dispw: int
     disph: int
     damaged: bool
     marked*: bool
     dead: bool
     kittyId: int
-    bmp: Bitmap
     # 0 if kitty
     erry: int
     # absolute x, y in container
@@ -643,11 +649,11 @@ proc outputGrid*(term: Terminal) =
   term.cursorx = -1
   term.cursory = -1
 
-func findImage(term: Terminal; pid, imageId: int; bmp: Bitmap;
-    rx, ry, erry, offx, dispw: int): CanvasImage =
+func findImage(term: Terminal; pid, imageId: int; rx, ry, width, height,
+    erry, offx, dispw: int): CanvasImage =
   for it in term.canvasImages:
     if not it.dead and it.pid == pid and it.imageId == imageId and
-        it.bmp.width == bmp.width and it.bmp.height == bmp.height and
+        it.width == width and it.height == height and
         it.rx == rx and it.ry == ry and
         (term.imageMode != imSixel or it.erry == erry and it.dispw == dispw and
           it.offx == offx):
@@ -669,8 +675,8 @@ proc positionImage(term: Terminal; image: CanvasImage; x, y, maxw, maxh: int):
   # origin (*not* offx/offy)
   let maxwpx = maxw * term.attrs.ppc
   let maxhpx = maxh * term.attrs.ppl
-  var width = int(image.bmp.width)
-  var height = int(image.bmp.height)
+  var width = image.width
+  var height = image.height
   if term.imageMode == imSixel:
     #TODO a better solution would be to split up the image here so that it
     # still gets fully displayed on the screen, or at least downscale it...
@@ -686,7 +692,7 @@ proc clearImage*(term: Terminal; image: CanvasImage; maxh: int) =
   of imNone: discard
   of imSixel:
     # we must clear sixels the same way as we clear text.
-    let ey = min(image.y + int(image.bmp.height), maxh)
+    let ey = min(image.y + image.height, maxh)
     let x = max(image.x, 0)
     for y in max(image.y, 0) ..< ey:
       term.lineDamage[y] = min(x, term.lineDamage[y])
@@ -699,10 +705,10 @@ proc clearImages*(term: Terminal; maxh: int) =
       term.clearImage(image, maxh)
     image.marked = false
 
-proc loadImage*(term: Terminal; bmp: Bitmap; data: Blob; pid, imageId,
-    x, y, rx, ry, maxw, maxh, erry, offx, dispw: int): CanvasImage =
-  if (let image = term.findImage(pid, imageId, bmp, rx, ry, erry, offx, dispw);
-      image != nil):
+proc loadImage*(term: Terminal; data: Blob; pid, imageId, x, y, width, height,
+    rx, ry, maxw, maxh, erry, offx, dispw: int): CanvasImage =
+  if (let image = term.findImage(pid, imageId, rx, ry, width, height, erry,
+        offx, dispw); image != nil):
     # reuse image on screen
     if image.x != x or image.y != y:
       # only clear sixels; with kitty we just move the existing image
@@ -714,7 +720,7 @@ proc loadImage*(term: Terminal; bmp: Bitmap; data: Blob; pid, imageId,
         return nil
     elif term.imageMode == imSixel:
       # check if any line of our image is damaged
-      let ey = min(image.y + int(image.bmp.height), maxh)
+      let ey = min(image.y + image.height, maxh)
       let mx = (image.offx + image.dispw) div term.attrs.ppc
       for y in max(image.y, 0) ..< ey:
         if term.lineDamage[y] < mx:
@@ -726,12 +732,13 @@ proc loadImage*(term: Terminal; bmp: Bitmap; data: Blob; pid, imageId,
     return image
   # new image
   let image = CanvasImage(
-    bmp: bmp,
     pid: pid,
     imageId: imageId,
     data: data,
     rx: rx,
     ry: ry,
+    width: width,
+    height: height,
     erry: erry
   )
   if term.positionImage(image, x, y, maxw, maxh):
@@ -751,7 +758,6 @@ proc outputSixelImage(term: Terminal; x, y: int; image: CanvasImage;
   let offy = image.offy
   let dispw = image.dispw
   let disph = image.disph
-  let bmp = image.bmp
   var outs = term.cursorGoto(x, y)
   outs &= DCSSTART & 'q'
   # set raster attributes
@@ -768,11 +774,11 @@ proc outputSixelImage(term: Terminal; x, y: int; image: CanvasImage;
   let L = data.len - lookupTableLen - 4
   # Note: we only crop images when it is possible to do so in near constant
   # time. Otherwise, the image is re-coded in a cropped form.
-  if realh == int(bmp.height): # don't crop
+  if realh == image.height: # don't crop
     term.write(data.toOpenArray(preludeLen, L - 1))
   else:
     let si = preludeLen + int(data.getU32BE(L + (offy div 6) * 4))
-    if disph == int(bmp.height): # crop top only
+    if disph == image.height: # crop top only
       term.write(data.toOpenArray(si, L - 1))
     else: # crop both top & bottom
       let ed6 = (disph - image.erry) div 6
@@ -803,7 +809,7 @@ proc outputSixelImage(term: Terminal; x, y: int; image: CanvasImage) =
 
 proc outputKittyImage(term: Terminal; x, y: int; image: CanvasImage) =
   var outs = term.cursorGoto(x, y) &
-    APC & "GC=1,s=" & $image.bmp.width & ",v=" & $image.bmp.height &
+    APC & "GC=1,s=" & $image.width & ",v=" & $image.height &
     ",x=" & $image.offx & ",y=" & $image.offy &
     ",w=" & $(image.dispw - image.offx) &
     ",h=" & $(image.disph - image.offy) &