diff options
author | bptato <nincsnevem662@gmail.com> | 2024-09-01 01:03:50 +0200 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2024-09-01 01:46:38 +0200 |
commit | 55cfd29e961488a8c1ed9eb7801d237d27bc86c7 (patch) | |
tree | c74569e15ca72d777eadcfd19a0203cbb76c3e3f /src/local | |
parent | e9466c4c436f964b53034e28356aa3f5c957a068 (diff) | |
download | chawan-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.nim | 2 | ||||
-rw-r--r-- | src/local/pager.nim | 55 | ||||
-rw-r--r-- | src/local/term.nim | 42 |
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) & |