about summary refs log tree commit diff stats
path: root/src/layout/engine.nim
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2024-04-25 01:06:43 +0200
committerbptato <nincsnevem662@gmail.com>2024-04-25 01:20:58 +0200
commit14b871eb7eaf329b67b71385597f114f8782318a (patch)
treeac7b4655124b4579ad27d56116d9a2dee63cd31e /src/layout/engine.nim
parent62944ac7abc6e37475739a1667ed5a0240fedf66 (diff)
downloadchawan-14b871eb7eaf329b67b71385597f114f8782318a.tar.gz
Initial image support
* png: add missing filters, various decoder fixes
* term: fix kitty response interpretation, add support for kitty image
  detection
* buffer, pager: initial image display support

Emphasis on "initial"; it only "works" with kitty output and PNG input.
Also, it's excruciatingly slow, and repaints images way too often.

Left undocumented intentionally it for now, until it actually becomes
useful.  In the meantime, adventurous users can find out themselves why:

[[siteconf]]
url = "https://.*"
images = true
Diffstat (limited to 'src/layout/engine.nim')
-rw-r--r--src/layout/engine.nim26
1 files changed, 20 insertions, 6 deletions
diff --git a/src/layout/engine.nim b/src/layout/engine.nim
index 99d205f5..30afb066 100644
--- a/src/layout/engine.nim
+++ b/src/layout/engine.nim
@@ -5,6 +5,7 @@ import std/unicode
 
 import css/stylednode
 import css/values
+import img/bitmap
 import layout/box
 import layout/layoutunit
 import types/winattrs
@@ -68,6 +69,7 @@ type
     text: seq[string]
     newline: bool
     splitType: set[SplitType]
+    bmp: Bitmap
 
   BlockBoxBuilder = ref object of BoxBuilder
     inlinelayout: bool
@@ -1500,8 +1502,20 @@ proc layoutInline(ictx: var InlineContext; box: InlineBoxBuilder):
   if ictx.firstTextFragment == nil:
     ictx.firstTextFragment = fragment
   ictx.lastTextFragment = fragment
-  ictx.layoutText(state, box.text)
-  ictx.layoutChildren(state, box.children)
+  if box.bmp != nil:
+    let iastate = InlineAtomState(
+      vertalign: state.computed{"vertical-align"},
+      baseline: ictx.cellheight
+    )
+    let atom = InlineAtom(
+      t: iatImage,
+      bmp: box.bmp,
+      size: Size(w: int(box.bmp.width), h: int(box.bmp.height)) #TODO overflow
+    )
+    discard ictx.addAtom(state, iastate, atom)
+  else:
+    ictx.layoutText(state, box.text)
+    ictx.layoutChildren(state, box.children)
   if stSplitEnd in box.splitType:
     let paddingRight = box.computed{"padding-right"}.px(lctx, ictx.space.w)
     ictx.currentLine.size.w += paddingRight
@@ -2856,10 +2870,10 @@ proc generateFromElem(ctx: var InnerBlockContext; styledNode: StyledNode) =
   of DisplayNone: discard
 
 proc generateAnonymousInlineText(ctx: var InnerBlockContext; text: string;
-    styledNode: StyledNode) =
+    styledNode: StyledNode; bmp: Bitmap = nil) =
   if ctx.iroot == nil:
     let computed = styledNode.computed.inheritProperties()
-    ctx.ibox = InlineBoxBuilder(computed: computed, node: styledNode)
+    ctx.ibox = InlineBoxBuilder(computed: computed, node: styledNode, bmp: bmp)
     if ctx.inlineStack.len > 0:
       let iparent = ctx.reconstructInlineParents()
       iparent.children.add(ctx.ibox)
@@ -2900,7 +2914,7 @@ proc generateReplacement(ctx: var InnerBlockContext;
     ctx.generateAnonymousInlineText(child.content.s, parent)
   of ContentImage:
     #TODO idk
-    ctx.generateAnonymousInlineText("[img]", parent)
+    ctx.generateAnonymousInlineText("[img]", parent, child.content.bmp)
   of ContentVideo:
     ctx.generateAnonymousInlineText("[video]", parent)
   of ContentAudio:
@@ -3116,7 +3130,7 @@ proc generateTableBox(styledNode: StyledNode; lctx: LayoutState;
   box.generateTableChildWrappers()
   return box
 
-proc renderLayout*(root: StyledNode; attrsp: ptr WindowAttributes): BlockBox =
+proc layout*(root: StyledNode; attrsp: ptr WindowAttributes): BlockBox =
   let space = AvailableSpace(
     w: stretch(attrsp[].width_px),
     h: stretch(attrsp[].height_px)